I have been doing a lot of programming in PHP, Perl, Java, Objective-C (has nothing to do with what we are talking about here, but just to mention) and other languages (sometimes python) where i did not really care about the way the informatiojn been sent and received between the client (browser) and the server, until i met Node.
Node had changed the way i think, i found in node what i used to think it should be always in programming languages ‘The Non blocking Code’ (it exist in some but at least not natively in PHP which is used by almost 70% of the database driven websites in the world including wikipedia).
Node is Javascript implementation, or whatever you call it, it runs javascript code on the server side, browsers runs javascript on the client (jQuery, dhtml, html5, svg – google these with javascript) also as javascript being the programming language used by mobile applications developers (check appcelerator for example, that produce native iphone, blackberry and android code from javascript), I thought it is the time to learn javascript as it should.
looking around, skimming few books, and trying javascript and node, i found that i need to focus and i am really lazy about focusing, it takes a lot of brain cells and time, until i met coffeescript.
Coffeescript is fantastic, it has it all, python style, easily readable code, and translates into javascript and last not least it does not produce any overhead.
Being said so, I started reading the documentation in coffeescript.org it is amazing, and the try coffeescript in the page allow you to write coffeescript and see how it looks like in javascript. WAW its helps me learn even javascript.
There are plenty of information around the internet about installing node and coffeescript, so I am going to skip all of this however i will present two links which will help in installing those : http://www.coffeescript.org and http://www.nodejs.org
I will start this tutorial, by showing how we can write a tiny small application (the hello world!) using coffeescript and run it using node.js
First thing first is to understand how web servers works. When a user goes to a website by typing the URL in the browser, the browser sends the information typed in the address box to the webserver and tell the server it finished sending information by sending what node.js translates as ‘end’, so when node sees ‘end’ coming from a web client, it means the web client finished sending information. Once the server receives the request and notified by the bye bye thank you (‘end’), the server will send header information, which tells the browser what type of information (or content) that will be sent as a reply to the request sent by the client and then the content itself then its say bye bye thank you.
One last thing to say here is that the server is a named as a server because it listens to a port and received the requests through it.
Let us translate this into code
Even though the code will end up to be javascript and the documentation is javascript, please follow with me as I am going to read it so i can use it with coffee script.
As programming languages wraps pieces of code together to ease producing applications whenever we need to use any of these pieces of ready code, we need to have present in our application by giving it a name to deal with it through this name, let us call the pieces of code which we will be using modules
so we need the http module which has all of the code that we can call to handle replying to browser requests, so as we require this in our program we need to assign it to a name
the name will be http that will use the required http module
http = require 'http'
as we are building a server, the first thing to start with is to create that server, and it is as simple as typing createserver the code of the server is in http itself
http.createServer will create the server.
The documentation of everything we need is in the website http://www.nodejs.org, let us look at what http has as methods to call, that exist in http://nodejs.org/docs/v0.6.5/api/http.html
as it says (and we did wrote this earlier) To use the HTTP server and client one must require(‘http’).
First thing you will encounter in the documentation of http is http.Server:
This is an EventEmitter with the following events,
this is not really what we want, we want to create a server at this moment.
what follows is
http.createServer([requestListener]) #
Returns a new web server object.
The requestListener is a function which is automatically added to the ‘request’ event.
this is exactly what we are looking for,
read carefully:
http.createServer returns a new web server object, and it accepts a function [requestlistener] : automatically added to the ‘request’ event
mmmm, let us check for the ‘request’ event in the documentation, in the same page we will find
Event: ‘request’ #
function (request, response) { }
Emitted each time there is a request. Note that there may be multiple requests per connection (in the case of keep-alive connections). request is an instance of http.ServerRequest and response is an instance of http.ServerResponse
few things here:
- emitted each time there is a request
- request is an instance of http.ServerRequest
- response is an instance of http.ServerResponse
before explaining the above let us write some code (using coffeescript)
http = require 'http'
we have now the http module available
now we can create the server
http.createServer [requestListener]
from what we learned
createServer returns a server object
and since it retruns object we will put the object in a variable, and
[requestListener] is the Event request, which is a function with two params request and response
so the code looks like this
server = http.createServer (request, response) ->
by creating this we are and as soon as he request is ready in this request listener we can reply via the response variable to the requester, however we need to listen really to the completed request
let us look at the http.ServerRequest as recommended
http.ServerRequest
This object is created internally by a HTTP server — not by the user — and passed as the first argument to a ‘request’ listener.
I think this is quite clear, what is interesting is what follows
This is an EventEmitter with the following events:
This is really cool, and this is actually what makes the server respond to different requests. The server itself can respond, as it only launches the ‘(request, response) -> ‘ code after it receives a request, but let us look at the different request type that can be captured by the request EventEmitter
Event: ‘data’ #
function (chunk) { }
Emitted when a piece of the message body is received.
Example: A chunk of the body is given as the single argument. The transfer-encoding has been decoded. The body chunk is a string. The body encoding is set with request.setEncoding().
Event: ‘end’ #
function () { }
Emitted exactly once for each request. After that, no more ‘data’ events will be emitted on the request.
Event: ‘close’ #
function () { }
Indicates that the underlaying connection was terminated before response.end() was called or able to flush.
Just like ‘end’, this event occurs only once per request, and no more ‘data’ events will fire afterwards.
Note: ‘close’ can fire after ‘end’, but not vice versa.
this is too much of information, let us go through it one by one:
Event:’data’
function (chunk) { }
Emitted when a piece of the message body is received.
I am not going to use it now, we will use in another tutorial
Event: ‘end’
function () { }
Emitted exactly once for each request. After that, no more ‘data’ events will be emitted on the request.
yes this means that i can go and send a response because i am not expecting anything,
Event: ‘close’ which could be fired only after ‘end’, just go and read about it in the documentation, i found what i am looking for.
to start a listener, i need to add it as the listener on the request, i can say
request.addListener
I am listening to ‘end’
so i can say
request.addListener 'end'
everything in nodejs should be assynchronous as possible and this is done via callback functions,
callback functions are just a parameter to a method, but it is a function.
so once request received a ‘end’, then it will fire the callback function and do its job
so the above could be written as such
request.addListener 'end', ->
my code resides here
the code to write is the code that can send a response back to the requesting browser or client, as we have seend earlier, there are two parameters that handle the callback of the connection to the server: request and response, response as we have seen, is an instance of http.ServerResponse.
it is time now to look at http.ServerResponse
again from the documentation
This object is created internally by a HTTP server–not by the user. It is passed as the second parameter to the ‘request’ event. It is a Writable Stream.
this is clear and confirms what we have explained earlier, now what is interesting is the method there, from the documentation again:
response.writeContinue()
response.writeHead(statusCode, [reasonPhrase], [headers])
response.statusCode
response.setHeader(name, value)
response.getHeader(name)
response.removeHeader(name)
response.write(chunk, encoding=’utf8′)
response.addTrailers(headers)
response.end([data], [encoding])
I don’t want to retype each one of these here, but if we recall what we said earlier, we need to start by sending a header information, send content and close the connection
so I am interested in writeHead, write and end
let us see how these works
- response.writeHead(statusCode, [reasonPhrase], [headers])
I beleive they were mistaken in the documentation and should have written it response.writeHead(statusCode[,reasonPhrase], [headers])
notice that the comma before the reasonPhrase to show that this is the second command and it is optional (as second command)
so reasonPhrase I never used it and don’t know why it I am going to using if ever, ending up with two arguments statusCode and headers,
for a complete http status code refer to http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html and for complete http headers http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
the status code we shall use is 200 (which means OK) and the headers we will be interested in is content-type which is enough to send to the browser (you could implement all of the response headers, it is up to you)
so my code will look like
response.writeHead 200, {'content-type': 'text/plain'}
response.write 'Hello World!'
response.end ''
since we are done with our code, we need to start listening to the port
server.listen 8000
and this listens to the port 8000
the final code
http = require 'http'
server = http.createServer (request, response) ->
request.addListener 'end', ->
response.writeHead 200, {'Content-Type': 'text/plain'}
response.write 'Hello World!'
response.end()
server.listen 8000
save it in a file called server.coffee
if we compile the code using
coffee --compile server.coffee
we get server.js
run it
node server.js
and open the browser to http://localhost:8000/
bingo… you are done.
later we will go deeper in coffeescript and node
please if you have any comments post them