REST Service with Node.js, MongoDB and Express

REST Service with Node.js, MongoDB and Express

Introduction

This is a tutorial showing how to connect a REST service to MongoDB. The REST service is written using Node.js and Express, we will assume that you have already gone through the previous tutorial which covered creating that service. If you haven’t, you can visit the tutorial here. Since explanations were already covered for some of the parts in the previous tutorial, we won’t re-visit the explanations here. We will only cover the code that is being changed for this tutorial.

The code for this tutorial is available here on github.

Setup The Environment

We are going to assume that you have already installed MongoDB (which is available here) and already have it running. If you haven’t already installed the mongodb node.js module, you can install it with this command:

npm install mongodb -g

Before you can start using the mongodb module, you will need to add it as a dependency. To do so, edit your package.json file to look like this:

{ "name": "application-name", "version": "0.0.1", "private": true, "scripts": { "start": "node app.js" }, "dependencies": { "express": "3.3.4", "mongodb":"*", "jade": "*", "stylus": "*" } }

Notice we have added the “mongodb” module with the version “*”. You can specify specific versions of the modules, which is usually preferred, but for this tutorial we should be ok with “*”. Lastly, we must execute this command to actually install the dependencies:

npm install -d

Writing The Code

Now we are ready to make the code changes. First we will create a new file called userProvider-mongodb.js with these contents:

var usersTable = 'users'; var Db = require('mongodb').Db; var Connection = require('mongodb').Connection; var Server = require('mongodb').Server; UserProvider = function(host, port) { this.db = new Db('users', new Server(host, port)); this.db.open(function(){}); this.fetchAllUsers = function(cb) { this.db.collection(usersTable, function(error, users) { if (error) { cb(error, null); } else { users.find().toArray(function(error, results) { cb(error, results); }); } }); }; this.fetchUserById = function(id, cb) { this.db.collection(usersTable, function(error, users) { if (error) { cb(error, null); } else { users.findOne({ _id:users.db.bson_serializer.ObjectID.createFromHexString(id) }, function(error, result) { cb(error, result); }); } }); }; this.insertUser = function(user, cb) { this.db.collection(usersTable, function(error, users) { if (error) { cb(error, null); } else { users.insert([user], function() { cb(null, user); }); } }); }; this.updateUser = function(user, cb) { this.db.collection(usersTable, function(error, users) { if (error) { cb(error, null); } else { users.update({_id:users.db.bson_serializer.ObjectID.createFromHexString(user._id)}, {name:user.name, state:user.state, city:user.city}, function(error, result) { cb(error, result); }); } }); }; this.deleteUser = function(id, cb) { this.db.collection(usersTable, function(error, users) { if (error) { cb(error, null); } else { users.remove({_id:users.db.bson_serializer.ObjectID.createFromHexString(id)}, function(error, result) { cb(error, result); }); } }); }; }; exports.UserProvider = UserProvider;

The first couple lines are simply importing some classes from the mongodb module. Notice we have added a constructor to the UserProvider class, which takes the host and port of the MongoDB server. In the first couple lines in the class, we create the Db object and open a connection.

We have the same methods in the class as were in the previous tutorial but this time instead of using a javascript array, we are storing it as a collection in MongoDB. For the fetchAllUsers method, we access the collection named ‘users’ and if there are no errors, we call the collection.find method with no parameters to get all objects in the collection. Finally we return this to the user, plain and simple!

Now, in the fetchUserById method, we again access the collection from the db and this time call the collection.findOne method and give it a query parameter, we look for any object with the _id field set to the id variable which was passed in, but first we have to convert it to an ObjectID from the hex string which we receive.

Take some time to look through the insert/update/delete User methods, they are all very similar and easy to understand. Now in order to use this provider, we have some minor modifications to make to the original userManager.js file:

var mongoServer = 'localhost'; var mongoPort = 27017; UserManager = function(app) { var UserProvider = require('./userProvider-mongodb').UserProvider; var userProvider = new UserProvider(mongoServer, mongoPort); 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 (error) { res.send(error, 404); } else { res.send(''); } }); }); app.delete('/users/:id', function(req, res) { userProvider.deleteUser(req.params.id, function(error, user) { if (error) { res.send(error, 404); } else { res.send(''); } }); }); }; exports.UserManager = UserManager;

Most of the file is the same with the exception of a few lines, most importantly these two lines which use the new userProvider-mongodb file and add the server and port to the constructor:

var UserProvider = require('./userProvider-mongodb').UserProvider; var userProvider = new UserProvider(mongoServer, mongoPort);

Testing the Service

That’s really all you need to do to get the service using MongoDB! You can test the service in the same way it was tested in the previous tutorial. To start up the service, again run the command:

node app.js

In the next tutorial in this series, I will cover adding a web interface to this service.