When we choose a technology to write an application, we don’t just choose the language, we also choose the list of available libraries. If a language has many useful libraries with a vibrant community around them, it’s going to be easier to write your application in less time.
The Breakthrough Presentation
Though Dahl started the Node project in early 2009, Node’s big day came when he gave a presentation on Node at JSConf Berlin in November. Significant attention from web developers for Node started after that conference, and has been growing since. Between the two JSConf conferences, Dahl was the only one to receive a standing ovation at the end of his talk. In a room of peers on the bleeding edge of their craft, that’s exciting.
There are arguably three main programming styles for implementing high-performance servers:
Using multiple processes,
multiple threads, or
single-threaded asynchronous events.
Node is an event-based framework and enforces a “no blocking APIs” policy throughout.
The multi-process or multi-threaded procedural style is the more common, conventional way to program in most other languages, like Java, C#, Perl, Python, Ruby, or PHP. Although event-based programming in those languages is possible, it is not the cultural norm. (Event-based frameworks in Python are available in Twisted or Tornado, and EventMachine in Ruby.)
Doing It with Events
For example, here’s how the jQuery documentation explains how to make an asynchronous (aka “Ajax”) request for data.
What does an event-based program in Node look like? Here’s a snippet of code from Dahl’s JSConf presentation:
In this example, a database query is made, but a callback function is attached. When the database returns results, the callback will be executed. Blocks of code are linked by events. When no database events have been triggered, the program is free to process other code and respond to other events.
Compare this to the more common procedural way this would be coded:
The problem with the the traditional example is that the program is blocked from doing anything else while waiting for results from the database. The traditional fix for that problem is to wrap the database call in a separate thread or process. At JSConf, Dahl explained that the event-based model is far more efficient with CPU and memory, while also scaling better. Compared to multi-process or multi-threaded programs, event-based frameworks can do more with less.
Getting Started with Node
Here’s the minimal path to start playing with the latest version of Node:
Out of the box, Node.js assumes it’s running in a POSIX environment—Linux or Mac OS X. If you’re on Windows, you’ll have to install MinGW to get a POSIX-like environment.
In Node, Http is a first-class citizen. Node is optimized for creating http servers, so most of the examples and libraries you’ll see on the internet will most likely focus on web topics (http frameworks, templating libraries, etc.)
Here’s a simple “hello world” web server:
Let’s examine the parts separately:
The createServer function expects to be given a callback to run every time a new request comes in.
Here’s how to run the example web server:
Even with this small amount of code, Node is fast enough to deploy as a real server. To measure server performance, Apache Bench is a great little utility for quick ad-hoc load testing. On my MacBook Pro (3.0 GHz Intel Core 2 Duo with 4GB 1067 MHz Ram), here’s how the “hello world” server performs with 10,000 requests, 4 multiple requests at a time.
Okay, So What’s the Catch?
Since Node is so new, there are many little features missing that that Rails and Django developers take for granted. During development, one small, yet important, feature that Node lacks is the ability to auto-restart when a change is made to the server’s source code. Other features like a step-debugger and REPL interactive prompt are available and useful, but still have some rough edges compared to equivalent tooling in Python and Ruby.
There’s a lot of churn going on in the Node codebase, with core APIs being modified between each release. Of course, these changes are making the APIs more consistent, so I’m not complaining. The pace of development is reminiscent of the early days of Ruby on Rails—there is a ton of innovation going on, but if you don’t pay attention for a week, many things are different. It’s the best and worst thing about the project. It’s great because more eyeballs means more bugs get fixed and new features get implemented faster. But it’s bad because you have to work hard to keep up with all the changes.