Sunday, February 17, 2013

Getting started with nodejs - building an MVC site

A couple of weeks ago I started getting into nodejs. At first I was quite skeptic, I don't even recall why, but after playing with it for just a couple hours I started loving it. Seriously, It's so simple to use, and it seems like the nodejs eco-system is growing really fast. I'm not going to go into what nodejs is or how it works, so if you don't know, you should start by reading this.

What I am going to show here, is a really quick and simple tutorial as to how to get started building a website on nodejs using the MVC design pattern. I'll go over the quick installation of nodejs and walk through getting the very basic mvc wireframe website up and running.
(Since I've been a .net developer for quite a while, I might be comparing some of the terms used to the terminology .net programmers are familiar with)

Installing nodejs
First, download and install nodejs.
On ubuntu, this would be :
sudo apt-get install nodejs
(If your ubuntu version is lower than 12.10 than you need to add the official PPA. Read this)

Now, you need to install the npm (nodejs package manager) :
sudo apt-get install nodejs npm
This will help us install packages built for nodejs. (exactly like 'Nuget' for Visual Studio users).

Starting our website
I've looked up quite a few mvc frameworks for nodejs, and I would say that the best one, by far, is expressjs. It's really easy to use and it's being actively updated.

Create a directory for your website, navigate their in the terminal, and type
sudo npm install express

Now we need to tell nodejs how to configure our application, where are the controllers/models/views, and what port to listen to...

Create a file called index.js in the website directory you created -

First things first :
var express = require('express');
app = express();

This defines 'app' as our expressjs web application, and gives us all the cool functionality that comes with the expressjs framework.

After that we need to configure our application :
app.configure(function() {
    app.set('view engine', 'jade');
    app.set('views', __dirname + '/views');
    
    app.use(express.logger());
    app.use(express.bodyParser());
    app.use(express.cookieParser());

    app.use(express.static(__dirname + '/scripts'));
    app.use(express.static(__dirname + '/css'));
    app.use(express.static(__dirname + '/img'));

    app.use(app.router);
});


The first two lines tells express we're going to use the 'jade' view engine to render our views. (This is like 'razor' but a little different, for people coming from the .net mvc). You can read about how the view engine works over here. The next 3 lines tell express to use certain middleware. ('middleware' are like 'filters' in the asp.net mvc world) middleware intercept each request, and can do what it wants, including manipulating the request. Basically, each middleware is a method being called with the request object, response object, and 'next' object respectively.
The 'next' object is a function that calls the next middleware in line.
All the middleware are called in the same order that they are defined. The middlewares I use here are basic middlewares that comes with the expressjs framework, and just make our life much easier (by parsing the request object, the cookies to our request/response objects and logging each request for us).

The final 3 lines of code, tell expressjs which directories have static files in them. This means that each request to a filename that exists in one of these files will be served as static content.
Note : if we put a file called 'main.css' in the '/css' folder, we request it by going to http://ourdomain.com/main.css and NOT by going to http://ourdomain.com/css/main.css. (This got me confused a little at first...)

After all that, we need to add our models and controllers...
require('./models');
require('./controllers');
The nodejs default when requiring a directory is to look for the file 'index.js' in that directory, so what I did is create an index.js file in each of those directories, and inside it just add a couple of 'require()' calls to specific files in that directory.

For models you can create javascript object however you like. On the projects I'm working on, I started using mongoose - which is like an ORM for mongodb. It's really simple to use, but I won't go into it for now...

Finally, in our init.js file, we need to tell our app to listen to a certain port -
app.listen(8888);

Controllers
Defining controllers is really easy with express - Each 'action' is a method, defined by GET or POST, the url (which can include dynamic parameters in it), and the function to call. A typical controller looks like this :
app.get('/about', function(request, response) {
    // just render the view called 'about'
    // this requires us to have a file called 'about.jade' in our 'views' folder we defined
    response.render('about');
});

app.get('/user/:userId', function(request, response) {
    // userId is a parameter in the url request
    response.writeHead(200); // return 200 HTTP OK status
    response.end('You are looking for user ' + request.route.params['userId']);
});

app.post('/user/delete/:userId', function(request, response) {
    // just a POST url sample
    // going to this url in the browser won't return anything..

    // do some work...
    response.render('user-deleted'); // again, render our jade view file
});


So, that's the end of this. It's really basic I know, but I hope it will help you get started... :)
The main idea of this post was to show just how easy it is to get started with nodejs.
I think I will be posting a lot more about nodejs in the near future! :)

Have fun! :)