Creating my first HTTP server in Node.js

Until now, my job as a front-end developer has been writing HTML, CSS and JS... I'm referring to the kind of JavaScript that affects elements in the browser, like adding behaviour to a site. That's what I considered a front-end developer to do. For a while things have been changing, as Gina Trapani points out in her fantastic post about learning modern JavaScript. My role has changed too; now I need to write server-side and client-side JavaScript, so I'm taking a leap and learning some Node.js.

This post focuses on the basics of creating a HTTP server. To write about everything I've learnt so far was too much for one blog post, so there will be at least another one or two posts coming soon to describe the rest.

Where to start

I haven't used any frameworks or tools yet. It was hard to find answers to my questions online that weren't aimed at sites using Express framework or a bunch of other modules. I'm aware that the code I've written probably isn't the proper way to do it, but it feels right to start with the language, before adding frameworks and tools. After all, frameworks and tools change, languages don't.

"First do it, then do it right, then do it better"

I love this advice from Addy Osmani (also mentioned by Gina Trapani). 

This is where I'm at. First I'm doing it, because I have to start somewhere (otherwise I'll never start at all). Then I'll learn how to do it right.

“First do it: Take a breath and acknowledge that you’re totally new to a space. It’s okay not to use everything. In fact, it’s better if you don’t. Get a simple prototype built that does the trick. Nothing wrong with straight-up using HTML/CSS/JS”.

Here's what I did:

1. Get node

Node.js can be downloaded from the site’s home page. We can type node -v into a terminal window to check it's installed. A version number should be returned.

Once node is installed, we can use the $node command in terminal. The command can be used with an argument or without. Typing  $node without an argument will open an interactive shell called REPL (read-eval-print-loop), which allows us to execute JavaScript. Now we can open a terminal window and type the following: 

$ node
>

Then type something like: 

> console.log('Hello World');

And get this:

Hello World
undefined

Nice, but it doesn't do a lot.

The other way to use the $node command (and the most common way) is to provide a JavaScript file as an argument. 

$ node server.js

This is how my project started. I created a directory, and then added a file named “server.js”. Inside server.js I started with a good old "Hello World" message for the console like this:

console.log("Hello World!");

So now when we type $node server.js , we get this:

Hello World!

Next I moved onto a more common use for node.

2. Create a HTTP server

There are several small, but significant steps involved in creating a HTTP server. This is what mine looks like so far:

var http = require('http');
var server = http.createServer(function(req, res) {
    res.writeHead(200, {"Content-Type": "text/html"});
    res.write("Hello World!");
    res.end();
});
server.listen(8000);
console.log("Server is listening, yeah!");

Let's break it down.

Line one var http = require('http');  is requiring the HTTP module. Node provides a module system. Like the HTTP module, some modules are included with node installations, so all we need to do is type this line. However, there are many more which are built by the large developer community which require a separate installation.

Next is to create the server object using the createServer method. This takes a callback function as an argument, which itself takes two arguments called req and res. Req contains information about the request (e.g. URL, HTTP headers, etc) and res contains information about the response.

So what's happening inside the callback function below? 

var server = http.createServer(function(req, res) {
    res.writeHead(200, {"Content-Type": "text/html"});
    res.write("Hello World!");
    res.end();
});

First it calls the res.writeHead() method. This sends a status code and header information to the client. For example, most of us have seen a 404 error code before, which indicates that a page can't be found. Whereas the code 200 means success. This header also defines the MIME type (content type) of the response. 

The res.write() method adds content to the page. UTF-8 character encoding is used by default or another one can be specified. So here, I've written: res.write("Hello World!");

To end the response we need to use the res.end()  method. This tells the server that the response is finished.

But for the whole thing to work, we need to bind the server to a port so it can listen for incoming connections, like this: server.listen(8000);  The client needs to know which port to connect to.

Here it is again: 

var http = require('http');
var server = http.createServer(function(req, res) {
    res.writeHead(200, {"Content-Type": "text/html"});
    res.write("Hello World!");
    res.end();
});
server.listen(8000);
console.log("Server is listening, yeah!");

Finally, we can see it in action in a browser at: http://localhost:8000/ 

And that's a HTTP server.

This post is part one. Part two is in progress.