Exploring a new frontier

yummy coffee

Beginning a few years ago, there have been a few projects – Rhino, Jaxer, more recently Narwhal – that proclaimed we were about to enter a golden era of server-side JavaScript programming. But the implementations always seemed to fall a bit short of expectations, and none of those projects have yet managed to generate the kind of attention and enthusiasm one might hope to see.

But then lately, and for the last few months, I’ve been hearing really good things about Node.js and when I saw this blog post I decided to give Node.js a shot.

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.

Ruby.

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.)

My contributions here involved expanding Ciaran’s very basic blog app to provide a few RESTful endpoints, and expanding his minimalistic Mongo-wrapper to also provide delete and update features. To make matters a little more challenging, I decided that I wanted to try writing the Express app in CoffeeScript – a variant, nicer syntax for JavaScript, that can be compiled into JavaScript.

Although CoffeeScript is easier to read and write than traditional JavaScript – borrowing good bits from both Ruby and Python, while still preserving the essential “javascriptiness” – I’ve never really warmed to the idea of writing for the browser in CoffeeScript, as it would seem to require some frequent re-compiling during development — true, there are resources available that help make that easier, it’s just never appealed to me. But I’m much less cautious of writing server-side code that way.

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”.

So, Express works reasonably well as a JSONified RESTful back-end for Cappuccino, with none of the “Mongo-in-a-straight-jacket” feeling I had with Ruby. And I think CoffeeScript is an instant “hit” – if one is already reasonably familiar with JavaScript, as well as at least one of Ruby or Python.

But it wasn’t all cotton candy and rainbows…

First, as familiar as I am with JavaScript, after a decade or more time writing it for browsers, it’s almost like learning a new language again. The server-side context is sufficiently different as to require a substantial shift in perspective (“you mean I don’t have to walk the DOM?”), and a new raft of tools (there are multiple, actively competing package managers for server-side JavaScript) to familiarize oneself with. I’d like to find something like Ruby’s irb (ie, a REPL for Node), to help explore the language in an interactive environment, with more immediate feedback.

Second, there’s a lot of moving pieces: in addition to my code, there’s CoffeeScript compiling syntaxes, Express setting up listeners and routing, and Node.js executing all that comes out. With all that’s going on “under the covers”, the “javascript stack” can be a little wobbly. I remember running into similar problems in the early days with Rails’ long, confusing stack traces being more than a little overwhelming.

Some examples of places where this bit me:

  • At one point, I was flummoxed by a “syntax error” from coffee, that turned out to be an unknown-to-me JavaScript reserved word — blindly assuming that “delete” routes worked in Express as they do in Sinatra, when “delete” in JavaScript nullifies properties on objects. (Express uses “del” instead of “delete”.)
  • 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.

Given that it’s still “early days” (both Node and Express are pre-version 1.0), all of this is understandable, and things will only improve from here. After a few years with Ruby, it seems like the “JavaScript guys” are approaching web development programming in reverse – build a super-fast server first, then follow up with a minimalist “framework”, and throw in some (optional) pretty syntax on top – and I mean that in a good way. Approaching things this way seems to have resulted in something that’s wicked fast, today – and that’s a great foundation to build on going forward.

Permalink • Posted in: javascript, web, programmingComments (4)

Scottish Ruby Conference

I'm very excited to be speaking at the Scottish Ruby Conference on Saturday. I've been an attendee at the conference (well, in its previous incarnation as Scotland on Rails) and it's one of my all-time favorite conferences.

My talk is on the challenges …

Permalink • Posted in: ruby, ruby on rails, travel, conferences, languageComments (1)

How to review a game

Let's start with how not to review a game. This is quite possibly the worst review ever. I don't know if the Star-Telegram reviews games often, but this is a phenomenally lazy attempt. They couldn't figure out how to play two of the games, so they give …

Permalink • Posted in: games, reviewsPost a comment

Thermostat

I wonder if some of the reason that there are so many Climate Change Skeptics in North America has to do with the overall temperature here being kinda coldish.

I mean, if you asked most North Americans how they'd like the temperature if it were a couple …

Permalink • Posted in: climate, cold, global warmingPost a comment

Is this thing on?

I'm contemplating starting to blog more regularly. Trying this on for size.

Permalink • Posted in: blogsPost a comment

Dominion

A little game called Dominion, possibly my favorite game in recent years, has just won a very prestigious game award, and is nominated for another — perhaps even more prestigious — award.

Dominion is a card game for 2-4 players (or up to …

Permalink • Posted in: gaming, newsComments (3)

Language filter

One of the spoiling things about living for two years where you don't fluently speak the local language, is that the range of external communication you can safely ignore expands dramatically. In fact, my brain's ability to filter irrelevant conversations …

Permalink • Posted in: moving, language, humorPost a comment

Moving bits

Standing in our new flat, looking south-east

Shower spray

When we inspected the new flat, along with the building management, we noticed spots of water hanging on the ceiling in the bathroom. “Must be something upstairs from us,” we said. “I’ll …

Permalink • Posted in: moving, torontoPost a comment

Concerning the thickness of fantasy novels

I love this detail from Brandon Sanderson's explanation of the decision to turn the final Wheel of Time novel into 3 parts:

When I'd mentioned 400k to him once, he'd been wary. He explained to me that he felt 400k was unprintably large in today's publishing …

Permalink • Posted in: books, links, fantasyPost a comment

Dog bites man, indeed

Some things should be, on the contrary, celebrated for their very groundedness and averageness and relatability. Human interest stories—when they’re of true human interest (rather than the products of cable’s attempts to sensationalize the serious …

Permalink • Posted in: news, words, linksPost a comment