<Marc Qualie/>

Introduction to Node.js: Building a Web Server

Lately I've been looking into different technologies for making real time communication better for my sites, games and apps. Node.js has been around for a while now, but it still doesn't seem to be picking up any traction in terms of it becoming widely adopted or used in big applications as far as I can tell. I've wanted to use it for quite a long time now, but never had the time. Lucky for me, I will be working on a project at work which requires real time communication so this is the perfect time to learn node and share my experience!

My first annoyance when it came down to getting into the code was lack of examples and useful documentation. This wasn't much of an issue once I got used to the syntax; I could just figure things out logically and break it until it worked. Let's start with the basic hello world example. Firstly, create a file called helloworld.js and put the below code into that file. Next you will want to run node helloworld.js from your console to start listening for connections.

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(8080);

This example is also available from the nodejs website, however I modified it to listen for external connections instead of just locally since I develop on an internal server, and not localhost. As nice as that is, you're going to want to do more that just say hello to your users. Next we will start playing with the file handling features of node to create our own simple version of an Apache web server.

However, before we jump in at the deep end and start making full blown servers, let's start with the basics of file handling. Below is a nice and simple Hello World demo, with a twist of reading the output from a .html file.

var http	= require('http'),
    fs		= require('fs'),
    url		= require('url'),
    path	= require('path');
http.createServer(function(req, res) {
    var filename = '.' + url.parse(req.url).pathname;
    if (filename == './') filename = 'index.html';
    path.exists(filename, function(exists) {
        if (!exists) {
            res.writeHeader(404, {"Content-type": "text/plain"});
            res.write('Error 404: File not found');
            res.end();
            return;
        }
        fs.readFile(filename, 'utf8', function(error, file) {
            if (error) {
                res.writeHeader(500, {"Content-type": "text/plain"});
                res.write('Internal File Error');
                res.end();
                return;
            }
            res.writeHeader(200, {"Content-type": "text/html"});
            res.write(file, 'utf8');
            res.end();
        });
    });
}).listen(8080);

The above code simply checks the URI you've specified, and looks for a file with that name in the current directory, then displays it to the user.

This next example is rather complex so instead of posting the code here I decided to host it on Github so you can access and download the code. As you read through the example you will see I've implemented a very basic templating engine, which is the start of a project I wish to pursue. Basically the goal will be to allow people to create web pages without every needing anything other than JavaScript and HTML knowledge, including interaction with the backend including database and file management! If you would like to take the code, or contribute to it then you can access the code on Github.

Here is a small example of the template system, in case you're interested without viewing the entire project

<ul class="files">
<node:files dir="/images">
    <li><a href="<file:url/>" title="<file:name/>"><file:name/></a></li>
</node:files>
</ul>

The above code will be parsed by node and a list of files will be printed using the above enclosed markup. Pretty simple, but allows you to create powerful client side displays with simple html markup. With a little though I'm sure you could come up with something a lot more exciting with the posibilites of a node templating engine!

If you have any questions about this post, or anything else, you can get in touch on Twitter or browse my code on Github.