Test driving node.js

After getting my bearings around JavaScript as a first class language, I wanted to try using it on a non-browser environment. Enter Node.js. The install was pretty simple on Ubuntu. Googling for a tutorial gives you this awesome ebook. It starts off with by an example of creating your own Http server. However my new found JavaScript powers made me impatient to drive on my own rather than follow exactly what the book says. In the space of one hour I churned out a rudimentary web application framework which could handle multiple Urls. Here’s some code to create an http server which listens on a port.

var http = require('http');
var router = require('./routers/router');
var routes = require('./routes/routes');

http.createServer(function(request, response){

 router.route(request, response, routes.list);


Notice the first few lines look like a Java import or a C# using statement. Since there is no built in syntax in the language for imports, the guys at node have improvised by assigning an object to a module. A module is like a package/namespace in Java/C#. A module can export functions or objects. There is a one to one mapping between a module and a file. It was something I missed on the browser and it works well.
Creating an http server is very simple; you just register a callback for every request. I created my own simple router function which takes in a the request, response and a list of routes. I didn’t couple the routes to the router because I can unit test the router independent of the routes.  The last line tells which functions/objects get exported for that module. It is analogous to Public methods/interfaces in conventional languages.

function route(request, response, routes) {
 if(routes == undefined || !routes[request.url]){

 console.log("Received request " + request.url);
 response.writeHead("404", {ContentType: "text/plain"});
 response.write("Route" + request.url + " not found");

 } else{

 routes[request.url](request, response);


exports.route = route

It checks if a route exists for a URL in the routes and calls the handler registered for the route. If there is no route, then it 404s with an error message. The routes is an object/associative  array with a handler function registered for different routes. It is quite similar to how a hash would be used in Ruby.

var healthCheckHandler = require("../handlers/health_check_handler");

exports.list = {

"/healthcheck" : healthCheckHandler.handleRequest


The last bit of code is just a handler for the health check URL. It just writes a canned response saying that the server is up.

function handleRequest(request, response){
 console.log("Health Check Handler Received request " + request.url);
 response.writeHead("200", {ContentType: "text/plain"});
 response.write("Server is up and running");

 exports.handleRequest = handleRequest;

The biggest advantage of using JavaScript for me is that you don’t have to create an object, if you don’t need it. The Router function would have been a class in a language like C# or Java. My first tendency was to go for the pattern, but then it occurred to me that the router is pure behaviour and doesn’t contain any data. Making it an object would couple the actual routes with behaviour and would make it less reusable and testable. The Routes however is an object, since it contains data on which url points to which request handler. Had it been a conventional language, I would have used the good old object hammer to pin ever nail. Since functions are truly first class citizens in JavaScript, it makes you think out of the object oriented box.

All in all, I am pretty convinced that node.js will slowly take over the world. 🙂


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s