Creating RESTfull API using node.js , express + mongoDB

restful-api-node-express-4-router

 

Here is a quick guide showing how to build a RESTful API using Node.js, Express, and MongoDB.

We will build a RESTful API for a library.  I will approach the problem by building an API for books only, and then scaling it to include all the other library items.

First Rollout: Build a Dumb Server

Before we start writing code, we need to fetch the dependencies. Even though the only dependency is Express, I like to keep a package.json file in case I ever decide to add other dependencies in the future. So, the first thing we will do is create a file called package.json and put the following code in it:

{
 name: library-rest-api,
 version:0.0.1,
 description:A simple library REST api,
 dependencies: {
 express:~3.1.0
 }
}

Now open up your terminal or command line and go to the project’s directory. Type “npm install” to install Express. It will be installed in the node_modules directory.Now that we have all the dependencies ready, let’s create a simple server that will capture requests and respond with a Hello World.

// Module dependencies.
var application_root = __dirname,
 express = require( 'express' ); //Web framework

//Create server
var app = express();

// Configure server
app.configure( function() {
 //parses request body and populates request.body
 app.use( express.bodyParser() );

 //checks request.body for HTTP method overrides
 app.use( express.methodOverride() );

 //perform route lookup based on url and HTTP method
 app.use( app.router );

 //Show all errors in development
 app.use( express.errorHandler({ dumpExceptions: true, showStack: true }));
});

//Router
//Get a list of all books
app.get( '/api/books', function( request, response ) {
 var books = [
 {
 title: "Book 1",
 author: "Author 1",
 releaseDate: "01/01/2014"
 },
 {
 title: "Book 2",
 author: "Author 2",
 releaseDate: "02/02/2014"
 }
 ];

 response.send(books);
});
//Insert a new book
app.post( '/api/books', function( request, response ) {
 var book = {
 title: request.body.title,
 author: request.body.author,
 releaseDate: request.body.releaseDate
 };

 response.send(book);
});
//Get a single book by id
app.get( '/api/books/:id', function( request, response ) {
 var book = {
 title: "Unique Book",
 author: "Unique Author",
 releaseDate: "03/03/2014"
 };

 response.send(book);
});
//Update a book
app.put( '/api/books/:id', function( request, response ) {
 response.send("Updated!");
});
//Delete a book
app.delete( '/api/books/:id', function( request, response ) {
 response.send("Deleted");
});

//Start server
var port = 4711;
app.listen( port, function() {
 console.log( 'Express server listening on port %d in %s mode', port, app.settings.env );
});

Save the file and run

node server.js

to start the server. The server should response with the hardcoded data when you try to get a book and should echo back the data when you try to do another operation, such as inserting, deleting, or updating.

Setting up the Database

Before you start using real data in your API, you need to install MongoDB or use a third-party service like MongoHQ. Please refer to the instructions on the MongoDB website to install MongoDB.

After you install MongoDB, create a database called library_database. Then, add a collection named “books” to the database. Run the database server (mongod), and you should be all set.

Second Rollout: Use Real Data

As always, before we start writing any code, we must have all the dependencies ready. The new dependency that we will introduce for this rollout is Mongoose. To install Mongoose, modify your package.json file to look as follows:


{
 "name": "library-rest-api",
 "version": "0.0.1",
 "description": "A simple library REST api",
 "dependencies": {
 "express": "~3.1.0",
 "mongoose": "~3.5.5"
 }
}

and run

npm install

To use Mongoose from our Node.js application, we first need to require it. Change the module dependencies code block to


// Module dependencies.
var application_root = __dirname,
express = require( 'express' ), //Web framework
path = require( 'path' ), //Utilities for dealing with file paths
mongoose = require( 'mongoose' ); //Used for accessing a MongoDB database

Then, we need to connect Mongoose to our database. We use the connect method to connect it to our local (or remote) database. Note that the url points to the database inside MongoDB (in this case it is library_database).

//Connect to database
mongoose.connect( 'mongodb://localhost/library_database' );

Mongoose provides two neat classes for dealing with data: Schema and model. Schema is used for data validation, and Model is used to send and receive data from the database. We will now create a Schema and a Model that adhere to our original data model.

//Schema
var BookSchema = new mongoose.Schema({
    title: String,
    author: String,
    releaseDate: Date
});
//Model
var BookModel = mongoose.model( 'Book', BookSchema );

Now we have everything ready to start responding to API requests. Since all of the request/response processing happens in the router, we will only change the router code it account for the persistent data. The new router should look as follows:


//Router
//Get a list of all books
app.get( '/api/books', function( request, response ) {
return BookModel.find(function( err, books ) {
if( !err ) {
return response.send( books );
} else {
console.log( err );
return response.send('ERROR');
}
});
});
//Insert a new book
app.post( '/api/books', function( request, response ) {
var book = new BookModel({
title: request.body.title,
author: request.body.author,
releaseDate: request.body.releaseDate
});
console.log(request.body.title);
book.save( function( err ) {
if( !err ) {
console.log( 'created' );
return response.send( book );
} else {
console.log( err );
return response.send('ERROR');
}
});
});
//Get a single book by id
app.get( '/api/books/:id', function( request, response ) {
return BookModel.findById( request.params.id, function( err, book ) {
if( !err ) {
return response.send( book );
} else {
console.log( err );
return response.send('ERROR');
}
});
});
//Update a book
app.put( '/api/books/:id', function( request, response ) {
return BookModel.findById( request.params.id, function( err, book ) {
book.title = request.body.title;
book.author = request.body.author;
book.releaseDate = request.body.releaseDate;

return book.save( function( err ) {
if( !err ) {
console.log( 'book updated' );
return response.send( book );
} else {
console.log( err );
return response.send('ERROR');
}
});
});
});
//Delete a book
app.delete( '/api/books/:id', function( request, response ) {
BookModel.findById( request.params.id, function( err, book ) {
return book.remove( function( err ) {
if( !err ) {
console.log( 'Book removed' );
return response.send( '' );
} else {
console.log( err );
return response.send('ERROR');
}
});
});
});

insert-books

Here we go, our REST API is now ready to roll.Happy coding 🙂

PS. This is how make it jsonp enable.

Add the ” app.set(“jsonp callback”, true);” to configuration. Now set response as jsonp as follows.

return response.jsonp( books );

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s