Exploring a new frontier
But: first a little background.
My latest project at work involves wrangling a sprawling horde of almost entirely arbitrary metadata. I've been really impressed with MongoDB's combination of traditional relational-database and new-fangled "document-oriented" features, but there's been a problem.
Well… kinda. Mostly. Basically.
There are a handful of MongoDB adapters for Ruby and/or Rails; my favorite tends to be MongoMapper. Except that, MongoMapper requires the developer to explicitly declare the model's attributes (ala DataMapper, MongoMapper's namesake) which, kinda, basically, mostly defeats the flexibility advantages of using something like Mongo in the first place.
There is also Candy which maintains most of Mongo's flexibility, but: 1) it doesn't "feel" like idiomatic Ruby (it diverges wildly from standard-bearer ActiveRecord, at least) and 2) it uses (painfully slow) method-missing "deep magic" to dynamically read and write from arbitrary attributes.
But also: I've been thinking that I might end up using something like Cappuccino as the front-end framework. In which case, I'd kind of like to just get the JSON that's coming out of Mongo, more or less unmolested, and let the fancy Objective-J client do the processing. For this particularly project, it started to feel that Ruby's obsession with object-relationship mapping was actively getting in the way.
And then sometime last week, I stumbled upon this tutorial by Ciaran Jessup that walks through creating a simple blog application (why do new web frameworks always start with blog tutorials?), written in Node.js, with database-backing provided by MongoDB.
His tutorial uses Express, a Node-powered http server that closely mirrors Ruby's Sinatra. This is where things start to feel familiar: I know my way around Sinatra, and I already tend to think Sinatra is a great "middle layer" for Cappuccino front-ends.
So: for the last few days, I've been hacking away on a little "proof of concept" project (you can follow along on github here), a "custom blend" of two tutorials: Ciaran's Node/Express/Mongo tutorial and this series on CappuccinoCasts about building a blog app backed by Rails.
The Cappuccino app is least changed from what's in the screencast, except that I threw in some bits working in Atlas (from a later episode), and had to figure out how to adjust Cappuccino's load paths to launch from the "static files" part of the Express app. (I'm a little disappointed in Atlas – for a "pay to play" beta, I expected something a little less buggy.)
So, how was it?
Well, first the good news: Node.js is fast. Insanely, unbelievably fast. Maybe this just tells you that I've spent too much time working with Ruby, but I found it astonishing. Posting a comment on the blog happens so quickly, I initially assumed it wasn't working — I thought, "it can't have done that so fast, there must be an error or something".
But it wasn't all cotton candy and rainbows…
irb (ie, a REPL for Node), to help explore the language in an interactive environment, with more immediate feedback.
Some examples of places where this bit me:
- Or, reading the stack trace from an error involving Express' "render" method, it looked to me that there were problems finding the specified template, but it turned out that Express was also trying to find a layout template (which had yet to be created), and failing loudly when it couldn't be located. (You can explicitly turn layouts off, but I had assumed it wouldn't require one anyway.)
Ultimately, Node.js and/or Express (realistically: and/or Coffee) might still be just a little too unstable. I found that small errors (sometimes including badly-formed JSON strings) could crash the entire server. Sure, some of that is my fault – bad code is bad code, afterall – and I know I can bring down a Ruby server, too, but it happened a bit more often than I'd like. I'm sure this will get better as Node and Express evolve, but for now, there's a tutorial available here on using Monit to keep Node alive.