Introduction

This is a simple tutorial showing how to create a REST service with Node.js using Express. This first tutorial will assume you have already installed Node.js, but it will walk you through installing Express and setting up a project. We will also show how to setup a simple REST service and how you can test it. In follow-up tutorials, we will show how to add a web page interface for interacting with the service, add authentication to the service and how to integrate with MongoDB for persistence.

If you are unfamiliar with Node.js, please visit their official website. Express is a web application framework for node.js, more info here.

The code for this tutorial is available here on github.

Setup The Environment

If you don't already have express installed, you can install it with the following command:

npm install express -g

You will want to create a new directory for your project, so create your project directory and then from within that directory, run the following command to create your new project shell.

express 

The express command generates a project using the jade template engine. Before we can run the project, we first need to install the dependencies. To install the dependencies, run the following command:

npm install -d

This command will download and install all of the dependencies into your project. You can now run your application and point your browser to http://localhost:3000, but it's just an empty shell right now, next we will create the code for the service. To run your project in its current state, use the command:

node app.js

Coding The Service

In our project directory we are going to create two new files in addition to the existing app.js, userManager.js and userProvider-array.js. The userManager.js will be our service and the userProvider-array.js will be our data layer that provides a user list to the service. Right now the userProvider is based on a javascript array and has no persistence, in future tutorials we will add persistence with mongodb.

Let's start by taking a look at the userProvider-array.js file:

var nextUserId = 1;
UserProvider = function() {
  this.users = [];
  this.fetchAllUsers = function(cb) {
    cb(null, this.users);
  };
  this.fetchUserById = function(id, cb) {
    var foundUsers = this.users.filter(function(user) {return user._id == id});
    if (foundUsers.length == 0) {
      cb('User not found', null);
    } else {
      cb(null, foundUsers[0]);
    }
  };
  this.insertUser = function(user, cb) {
    user._id = nextUserId++;
    this.users.push(user);
    cb(null, user);
  };
  this.updateUser = function(user, cb) {
    this.fetchUserById(user._id, function(error, _user) {
      if (error) {
        cb(error, null);
      } else {
        _user.name = user.name;
        _user.city = user.city;
        _user.state = user.state;
        cb(null, _user);
      }
    });
  };
  this.deleteUser = function(id, cb) {
    this.users = this.users.filter(function(user) {return user._id != id});
    cb(null, {_id:id});
  };
};
exports.UserProvider = UserProvider;

Here we have created a UserProvider class with several methods for accessing a list of users.

  • fetchAllUsers - Fetches all users.
  • fetchUserById - Fetches a user by its _id property.
  • insertUser - Creates a user based on the given user object.
  • updateUser - Updates the details of a user by its _id property.
  • deleteUser - Deletes a user by its _id property.

Keeping with the spirit of node.js, everything is event driven, so you pass a callback method to each of these methods. It's not really that necessary for this array based implementation but when we get to doing real I/O it will become very useful.

Next we move on to the code for the userManager.js file, which is the actual service which will make use of this data provider.

UserManager = function(app) {
  var UserProvider = require('./userProvider-array').UserProvider;
  var userProvider = new UserProvider();
  userProvider.insertUser({_id:1, name:'Rocky', city:'Omaha', state:'NE'}, function(a,b){});
  userProvider.insertUser({_id:2, name:'Dave', city:'Stafford', state:'VA'}, function(a,b){});
  app.get('/users', function(req, res) {
    userProvider.fetchAllUsers(function(error, users) {
      res.send(users);
    });
  });
  app.post('/users', function(req, res) {
    userProvider.insertUser(req.body, function(error, user) {
      if (error) {
        res.send(error, 500);
      } else {
        res.send(user);
      }
    });
  });
  app.get('/users/:id', function(req, res) {
    userProvider.fetchUserById(req.params.id, function(error, user) {
      if (user == null) {
        res.send(error, 404);
      } else {
        res.send(user);
      }
    });
  });
  app.post('/users/:id', function(req, res) {
    var _user = req.body;
    _user._id = req.params.id;
    userProvider.updateUser(_user, function(error, user) {
      if (user == null) {
        res.send(error, 404);
      } else {
        res.send(user);
      }
    });
  });
  app.delete('/users/:id', function(req, res) {
    userProvider.deleteUser(req.params.id, function(error, user) {
      if (user == null) {
        res.send(error, 404);
      } else {
        res.send(user);
      }
    });
  });
};
exports.UserManager = UserManager;

This class has a constructor which takes the express app object. With this object we can add routes for the service. The first thing we do is create a new instance of UserProvider and then add a couple data rows to it. The methods for creating routes follow this basic design:

app.<http_method>(<url-path>, function(requestObject, responseObject) {
});

Finally, we wrap it all together by editing the app.js file so that it looks like this:

var express = require('express')
  , routes = require('./routes')
  , user = require('./routes/user')
  , http = require('http')
  , path = require('path');
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(require('stylus').middleware(__dirname + '/public'));
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
  app.use(express.errorHandler());
}
var UserManager = require('./userManager').UserManager;
var userManagerService = new UserManager(app);
http.createServer(app).listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});

Now you can run your REST service and test it out by starting it with this command:

node app.js

Testing The Service

You are now ready to test your REST service, I would suggest using the Advanced Rest Client Chrome Plug-in. It's an excellent free utility for testing REST services of all shapes and forms. Here is a screenshot of using it to test the very first fetchAllUsers method:

Notice that we set http://localhost:3000/users as the URL for our fetchAllUsers request and we can see the following JSON response:

[
  {
    "_id": 1,
    "name": "Rocky",
    "city": "Omaha",
    "state": "NE"
  },
  {
    "_id": 2,
    "name": "Dave",
    "city": "Stafford",
    "state": "VA"
  }
]

We can also lookup users by their ID, such as http://localhost:3000/users/1, which produces:

{
    "_id": 1,
    "name": "Rocky",
    "city": "Omaha",
    "state": "NE"
}

Play around with the POST and DELETE methods to add/update and delete users from the array.

This concludes the first part of this tutorial, in the next tutorial we will change the array based provider to use MongoDB so that the storage is persistent.

The following two tabs change content below.

Rocky Pulley

Solutions Architect at QAT Global
is a Solutions Architect at QAT Global and has been working as a software development consultant for over 15 years. Most of his recent work has been focusing on Web 2.0 technologies and mobile application development. @rockytriton