Skip to content
Tags

Experimenting with Node.js

September 13, 2011

Over the weekend I began thinking about my PRJ666 project and what language we are going to code the back end in.  The client wants everything to be free, so we can’t purchase any additional license’s to use something like c# or anything.  The front end stuff was all going to be done in javascript as I’ve had quite a bit of experience in it over the last few months, so it seemed like a simple choice.  Initially i figured I would just do the back end in php and be done with it, but after some talking with people in irc and snooping across the internet I remembered Node.js.  This seemed like a perfect opportunity to try something like node.js out and if it failed miserably I could simply take it as a learning experience, I mean, thats what schools for right?  I still havnt told my team about my decision, and if your reading this, SURPRISE!

What is Node.js?

Before now, Javascript code has been primarily written on the client side, that is, in the browser.  What Node.js does is allow you to run server side javascript code, which for someone like me who loves Javascript, is awesome.  Node.js achieves this by interpreting Javascript and executing it using Google’s V8 VM ( the same runtime enviroment they use for Chrome ).  Not only is Node.js an interpreter, but it is also a library, providing an easy way for users to create servers written in javascript.

A short example

After reading a bunch about Node.js, I had to give it a try.  I installed Node.js using the instructions that they have up on their git repo.  The instructions were straight forward ( after I actually took the time to read them instead of rushing over them ).  After giving it a try I admittedly screwed it up, which is typical for me.  I went to the irc channel ( #node.js on irc.freenode.net ) that was filled with hundreds of other developers asking various questions, which was really cool.  I asked my newbie question about what I was doing wrong and not 10 seconds later I got an answer.  For such a large channel I was not expecting to get an answer so fast.  What I was trying to do was install Node.js package manager called npm.  It turns out that npm is not up and running on there current develop branch, so I was instructed to revert back to a stable version of 0.4.11.  Cool, everything was up and running smoothly after this.  I then began reading and trying out some tutorials.  A side note, but one of the most appealing parts of Node.js was how modular it was, which reminded me of the Butter API that the guys at CDOT and I wrote not too long ago.

Essentially what I wanted to accomplish when I was trying it was the following:

  • Display a server side page
  • Create some idea of navigation on the back end
  • Have the server spit out some messages

Believe it or not, all of this was actually quite painless ( albeit I was following a guide, but understanding it was just like reading any other Javascript ).  The first thing I did was create a index.js file which is just a general starting point, similar to an index.html file. This looked like the following:


var server = require("./server");
var router = require("./router");
var requestHandlers = require("./requestHandlers");

var handle = {}
handle["/"] = requestHandlers.start;
handle["/start"] = requestHandlers.start;
handle["/upload"] = requestHandlers.upload;

server.start(router.route, handle);

What this does is creates 3 variables to start with, that tells our server that we are going to need to use these files in our program.  We pass it a path to where these files are located.  Next we create an object called handle, and create some key value pairs.  What this is doing is essentially telling the server what functions to call when certain pages make requests.  Since we told our server that we need the files that we outlined at the top, we can now make function calls from these files, by calling our servers start function, passing it in our routers route function and the handler object that we just created. Awesome!

The next file we need to implement is our server.js file, which looks like the following:


var http = require("http");
var url = require("url");

function start(route, handle) {
function onRequest(request, response) {
var pathname = url.parse(request.url).pathname;
console.log("Request for " + pathname + " received.");

response.writeHead(200, {"Content-Type": "text/plain"});
var content = route(handle, pathname);
response.write(content);
response.end();
}

http.createServer(onRequest).listen(8888);
console.log("Server has started.");
}

exports.start = start;

What we do here is include our http and url modules, assinging them to a variable for later use, create a start function that wraps the onRequest function, and filled out the insides of these functions with some logic.  We essentially wrapped the onRequest function with start as we need some variables to be passed in later on, which will be explained in another file.  Inside onRequest we use our url module to parse the pathname from the url that made the request, which is stored in our request variable that was passed into request. We then log this pathname.  We then write to the head of our client side page.  The content variable stores the result from the route function ( later explained ) and then writes the result and then ends the write.  After this ( this happens before any requests are handled, but im explaining from the top down so yea ) we create our server and tell it which port to listen on.  We tell it that requests will be handled by the function onRequest ( implemented above it ).  We then do another log that our server has indeed started.

The next file is our router.js file, which essentially does what it sounds like, routes stuff.  This looks like the following:


function route(handle, pathname) {
console.log("About to route a request for " + pathname);
if (typeof handle[pathname] === 'function') {
return handle[pathname]();
} else {
console.log("No request handler found for " + pathname);
return "404 Not found";
}
}

exports.route = route;

We create a route function, with a handle and pathname variables.  We log the pathname variable, and then perform some checks.  If the value that is stored with the key of pathname in handle is a function, then we simply call that function. If it is not a function, then we log that there was no request handler found for this pathname ( no page to display ).

The last page we create is our requestHandlers.js file, which essentially just returns a string for what page we are on. This is where logic for each page would be implemented in a more in depth server scenario.  It looks like the following:


function start() {
console.log("Request handler 'start' was called.");
return "Hello Start";
}

function upload() {
console.log("Request handler 'upload' was called.");
return "Hello Upload";
}

exports.start = start;
exports.upload = upload;

We essentially create a start and upload function, log some data, and then return some data.  These are called by our key value pairs from before, which were assigned these functions in our index.js file.

What we have essentially done here is seperated our code into modules and exported the parts of the module that we want to expose to scripts that are including this module, which is our index.js file.  Since this file is our starting point, and everything is set up here, it works.

We then, on command line, run the following command: node index.js

Thats it. Our server has now started.  To view our webpage, go to localhost:8888.

The command line will look like the following, and the webpage will look like the following as well.

If we navigate to different pages, it will look like the following:

And the command line after all those page navigates will look like the following:

This whole implementation took me about half an hour and worked flawlessly so far.  Being able to write in a language that I am super comfortable in was a sigh of relief.  I cant wait to experiment some more with Node.js and really get into the nitty gritty of it.  My next plan is to implement a simple database and see how that goes.

4 Comments
  1. Good Job. Please keep posting. Have you decided on the objectives for your project?

    • Thanks!
      The project is for one of my classes in college. We need to take on an actual client ( in this case a higher end restraunt ) and design and implement a system that they need. Last winter we designed and scoped the project, proposed it to the client and got it accepted. This semester we are implementing it. The project is essentially an inventory system and a way to track invoices and what is being purchased. It will log a history of prices for each supplier over time, to enable the company to buy effectively. They don’t have anything in place now to track this sort of stuff, so this should be really cool!

  2. Spyro7 permalink

    This is a fantastic post! Keep it up!

    Hey, have you taken a look at expressjs yet? It is the nodejs equivalent to sinatra in the ruby world (think of it like rails-lite):

    http://expressjs.com/

Leave a reply to Charles Short Cancel reply