• Menu
  • Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar

JavaBeat

Java Tutorial Blog

  • Java
    • Java 7
    • Java 8
    • Java EE
    • Servlets
  • Spring Framework
    • Spring Tutorials
    • Spring 4 Tutorials
    • Spring Boot
  • JSF Tutorials
  • Most Popular
    • Binary Search Tree Traversal
    • Spring Batch Tutorial
    • AngularJS + Spring MVC
    • Spring Data JPA Tutorial
    • Packaging and Deploying Node.js
  • About Us
    • Join Us (JBC)
  • Java
    • Java 7
    • Java 8
    • Java EE
    • Servlets
  • Spring Framework
    • Spring Tutorials
    • Spring 4 Tutorials
    • Spring Boot
  • JSF Tutorials
  • Most Popular
    • Binary Search Tree Traversal
    • Spring Batch Tutorial
    • AngularJS + Spring MVC
    • Spring Data JPA Tutorial
    • Packaging and Deploying Node.js
  • About Us
    • Join Us (JBC)

RESTful Example using ExpressJS + Node.js + MongooseJS

May 18, 2015 //  by Mohamed Sanaulla//  Leave a Comment

RESTful Web Services Example : ExpressJS + Node.js + MongooseJS

In my previous articles I have explaines about CRUD operations Node.js + MongoDB – Performing CRUD Operations and Mongoose – Node.js + MongoDB with Mongoose Tutorial. In this post I will show you how to create CRUD operations using RESTful Web Services and ExpressJS with MongooseJS. I would be using the following 3 Node packages for this sample namely:

  1. ExpressJS
  2. body-parser
  3. MongooseJS

ExpressJs

From the Node Package manager website:

Fast, unopinionated, minimalist web framework

Express is used to create Web applications using Node.js. It provides support for routes, setting up view templates and others. This is most popular Node.js web framework as of now. The advantage of using ExpressJS is to reduce the time and lines of code written unless using the plain Node.js modules.

Body-parser

From the Node Package manager wwebsite:

Node.js body parsing middleware.

This middleware is used for intercepting the requests, parsing the request body and then populating it in the node.js’s req object.

MongooseJS

From the Node Package Manager website:

MongooseJS is a MongoDB object modeling tool designed to work in an asynchronous environment.

This is used to define Model objects and then use it to interact with MongoDB, a kind of ORM in the OO Programming world. MongooseJS is a Object Data Mapping (ODM) for JavaScript frameworks. This helps you to map the JavaScript objects to the MongoDB database. This tool is developed and maintained by the MongoDB community itself.

enm

Defining the RESTful API

In this tutorial I am going to implement a simple RESTful Web Services (Read : Spring REST Web Services) example using ExpressJS ,Node.js and MongooseJS. The right below section just defines the list of operations that are going to implemented as part of the excersise. The list of RESTful APis are :

  • Fetch list of all books in the system : GET /book/
  • Fetch details of a book in the system : GET /book/:isbn
  • Add a new book to the system : POST /book/
  • Edit details of existing book in the system : PUT /book/:isbn
  • Delete given book from the system : DELETE /book/:isbn

1. Fetch list of all books in the system : GET /book/
Parameters: No parameters
Response: The response is going to be an array of JSON objects (Also Read : What is JSON?) with the structure given below.

[
  {
    "_id":STRING,
    "name":STRING,
    "isbn":STRING,
    "author":STRING,
    "pages":INTEGER,
    "_v":STRING
  }
]

2. Fetch details of a book in the system : GET /book/:isbn
Parameters: ISBN of the book
Response: The response is going to be the JSON object with the structure given below.

{
  "_id":STRING,
  "name":STRING,
  "isbn":STRING,
  "author":STRING,
  "pages":INTEGER,
  "_v":STRING
}

3. Add a new book to the system : POST /book/
Parameters: Data of following format has to be sent in the request body

{
  "name":STRING,
  "isbn":STRING,
  "author":STRING,
  "pages":INTEGER
}

Response: The response is going to be the JSON object with the structure given below.

{
    "messaage": "Successfully added book",
    "book": {
        "__v": STRING,
        "name": STRING,
        "isbn": STRING,
        "author": STRING,
        "pages": INTEGER,
        "_id": STRING
    }
}

4. Edit details of existing book in the system : PUT /book/:isbn
Parameters: ISBN of the book and the updated book information in the below format in request body.

{
  "name":STRING,
  "isbn":STRING,
  "author":STRING,
  "pages":INTEGER
}

Response: The response is going to be the JSON object with the structure given below.

{
    "messaage": "Successfully updated the book",
    "book": {
        "__v": STRING,
        "name": STRING,
        "isbn": STRING,
        "author": STRING,
        "pages": INTEGER,
        "_id": STRING
    }
}

5. Delete given book from the system : DELETE /book/:isbn
Parameter: ISBN of the book to be deleted
Response: The response is going to be the JSON object with the structure given below.

{
    "messaage": "Successfully deleted the book",
    "book": {
        "__v": STRING,
        "name": STRING,
        "isbn": STRING,
        "author": STRING,
        "pages": INTEGER,
        "_id": STRING
    }
}

Implementing the RESTful API : ExpressJS + Body-parser + Node.js

As mentioned earlier I would be using express.js, node.js and body-parser.js node packages with MongooseJS. The below code sets up the packages and starts the web server on port 3300.

//Express is required for creating Node.js based web apps
var express = require('express');

//body-parser is used to parse the Request body and populate the req.
var bodyParser = require('body-parser');

//mongoose is used for interacting with MongoDB
var mongoose = require('mongoose');

var app = express();
app.set('port', 3300);

//Configuring Express App to make use of BodyParser's JSON parser to parse
//JSON request body
app.use(bodyParser.json());

var dbHost = 'mongodb://localhost:27017/test';
mongoose.connect(dbHost);
//Create a schema for Book
var bookSchema = mongoose.Schema({
  name: String,
  //Also creating index on field isbn
  isbn: {type: String, index: true},
  author: String,
  pages: Number
});

//Create a Model by using the schema defined above
//Optionally one can provide the name of collection where the instances
//of this model get stored. In this case it is "mongoose_demo". Skipping
//this value defaults the name of the collection to plural of model name i.e books.
var Book = mongoose.model('Book', bookSchema);

//Connecting to Mongod instance.
mongoose.connection;

//Starting up the server on the port: 3300
app.listen(app.get('port'), function(){
  console.log('Server up: http://localhost:' + app.get('port'));
});

You can save the above code in file: express_demo.js and then run it using node express_demo.js , you should be able to see the below output:

Server up: http://localhost:3300

Implementing GET /book

The below code implements this API:

//Get all the books
app.get('/book', function(req, res){
  //Find all the books in the system.
  Book.find({}, function(err, result){
    if ( err ) throw err;
    //Save the result into the response object.
    res.json(result);
  });
});

In ExpressJS we create an application instance using express() (as seen above) and then setup the routes using the application instance. For example, for a GET call we use applicationInstance.get("ROUTE", handler(req, res){}), for a POST call we would set it up as applicationInstance.post("ROUTE", handler(req, res){}) and so on for other HTTP Methods like PUT, DELETE and others.

Implementing GET /book/:isbn

The below code is the implementation of the API

//Get the details of the book with the given isbn
app.get('/book/:isbn', function(req, res){
  console.log("Fetching details for book with ISBN: " + req.params.isbn);
  //The parameter in the route is accessed via request.params object.
  Book.findOne({isbn: req.params.isbn}, function(err, result){
    if ( err ) throw err;
    res.json(result);
  });
});

In this Implementation the following are points of observation:

  1. Creating parameterized routes by using the :variable_Name in the route definition. In this case I have defined the route as /book/:isbn and this matches any url of form /book/abc123
  2. Accessing the path variable in the route via the request.params object. In this case I retrieve the ISBN string passed in the URL via req.params.isbn
  3. Using findOne with query object. In this case I am making use of MongoDB’s findOne() API along with the query object which is built using the ISBN information passed to retrieve one book information matching the ISBN

Implementing POST /book

This API is used to add a new book to the system. The information of the book is to be passed in the request body and we make use of the body-parser module to parse the json in the request body and populate it in the Node’s request object. The below code implements this API

//Add a new book
app.post("/book", function(req, res){
  console.log("Adding new Book: " + req.body.name);
  var book = new Book({
    name:req.body.name,
    isbn: req.body.isbn,
    author: req.body.author,
    pages: req.body.pages
  });

  //Saving the model instance to the DB
  book.save(function(err, result){
    if ( err ) throw err;
    //After successfully saving the book we generate a JSON response with the
    //message and the inserted book information.
    res.json({
      messaage:"Successfully added book",
      book:result
    });
  });
});

In this implementation we read the JSON data passed by the Client, populate our instance of Book model class and persist the same to the DB using Mongoose API.

Implementation PUT /book/:isbn

This implementation is similar to GET /book/:isbn in terms of parameter handling and POST /book in terms of handling the book data passed from the client. We query for the existing information in the DB and then populate this existing data with the data passed from the client.

//Update an existing book
app.put("/book/:isbn", function(req, res){
  Book.findOne({isbn: req.params.isbn}, function(err, result){
    if ( err ) throw err;

    if(!result){
      res.json({
        message:"Book with ISBN: " + req.params.isbn+" not found.",
      });
    }

    result.name   = req.body.name;
    result.isbn   = req.body.isbn;
    result.author = req.body.author;
    result.pages  = req.body.pages;

    result.save(function(err, result){
      if ( err ) throw err;
      res.json({
        message:"Successfully updated the book",
        book: result
      });
    });

  });
});

Implementing DELETE /book/:isbn

Again this implementation is similar to GET /book/:isbn in terms of parameter handling and finding the book from the DB. To delete the book information we make use of findAndRemove API in Mongoose.

//Delete an existing book
app.delete("/book/:isbn", function(req, res){
  Book.findOneAndRemove({isbn: req.params.isbn}, function(err, result){
      res.json({
        message: "Successfully deleted the book",
        book: result
      });
  });
});

Testing the REST APIs

Now that I have shown you the implementation of individual APIs, lets go ahead and test the implemented APIs. For testing POST, PUT, DELETE I am making use of Postman Client’s plugin for Chrome.

GET /book

GET /book

GET /book/:isbn

GET /book/:isbn

POST /book

POST

PUT /book/:isbn

PUT

DELETE /book/:isbn

DELETE

Wrapping Up

I have shown you how the REST API is designed and then implemented using ExpressJS, Node.js and MongooseJS. For those looking for complete solution, copy the below code into a file named: express_demo.js

//Saved in file: express_demo.js
//Express is required for creating Node.js based web apps
var express = require('express');

//body-parser is used to parse the Request body and populate the req.
var bodyParser = require('body-parser');

//mongoose is used for interacting with MongoDB
var mongoose = require('mongoose');

var app = express();
app.set('port', 3300);

//Configuring Express App to make use of BodyParser's JSON parser to parse
//JSON request body
app.use(bodyParser.json());

var dbHost = 'mongodb://localhost:27017/test';
mongoose.connect(dbHost);
//Create a schema for Book
var bookSchema = mongoose.Schema({
  name: String,
  //Also creating index on field isbn
  isbn: {type: String, index: true},
  author: String,
  pages: Number
});

//Create a Model by using the schema defined above
//Optionally one can provide the name of collection where the instances
//of this model get stored. In this case it is "mongoose_demo". Skipping
//this value defaults the name of the collection to plural of model name i.e books.
var Book = mongoose.model('Book', bookSchema);

//Connecting to Mongod instance.
mongoose.connection;

//Starting up the server on the port: 3300
app.listen(app.get('port'), function(){
  console.log('Server up: http://localhost:' + app.get('port'));
});

//Get the details of the book with the given isbn
app.get('/book/:isbn', function(req, res){
  console.log("Fetching details for book with ISBN: " + req.params.isbn);

  Book.findOne({isbn: req.params.isbn}, function(err, result){
    if ( err ) throw err;
    res.json(result);
  });
});

//Get all the books
app.get('/book', function(req, res){
  //Find all the books in the system.
  Book.find({}, function(err, result){
    if ( err ) throw err;
    //Save the result into the response object.
    res.json(result);
  });
});

//Add a new book
app.post("/book", function(req, res){
  console.log("Adding new Book: " + req.body.name);
  var book = new Book({
    name:req.body.name,
    isbn: req.body.isbn,
    author: req.body.author,
    pages: req.body.pages
  });

  //Saving the model instance to the DB
  book.save(function(err, result){
    if ( err ) throw err;
    res.json({
      messaage:"Successfully added book",
      book:result
    });
  });
});

//Update an existing book
app.put("/book/:isbn", function(req, res){
  Book.findOne({isbn: req.params.isbn}, function(err, result){
    if ( err ) throw err;

    if(!result){
      res.json({
        message:"Book with ISBN: " + req.params.isbn+" not found.",
      });
    }

    result.name   = req.body.name;
    result.isbn   = req.body.isbn;
    result.author = req.body.author;
    result.pages  = req.body.pages;

    result.save(function(err, result){
      if ( err ) throw err;
      res.json({
        message:"Successfully updated the book",
        book: result
      });
    });

  });
});

//Delete an existing book
app.delete("/book/:isbn", function(req, res){
  Book.findOneAndRemove({isbn: req.params.isbn}, function(err, result){
      res.json({
        message: "Successfully deleted the book",
        book: result
      });
  });
});

Before running this you would have to install the following packages: express, body-parser, mongoose using the command npm install.

Reference Books for Node.js

  • Professional Node.js: Building Javascript Based Scalable Software (English)
  • MongoDB : The Definitive Guide (English) 2nd Edition
  • MongoDB in Action (English)

Category: ExpressJS, MongoDB, NodeJSTag: NodeJS Tutorials

About Mohamed Sanaulla

In his day job he works on developing enterprise applications using ADF. He is also the moderator of JavaRanch forums and an avid blogger.

Previous Post: « Mongoose – Node.js + MongoDB with Mongoose Tutorial
Next Post: HOW TO : SignIn with Twitter using Node.js and Express.js »

Reader Interactions

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Primary Sidebar

Follow Us

  • Facebook
  • Pinterest

FEATURED TUTORIALS

New Features in Spring Boot 1.4

Difference Between @RequestParam and @PathVariable in Spring MVC

What is new in Java 6.0 Collections API?

The Java 6.0 Compiler API

Introductiion to Jakarta Struts

What’s new in Struts 2.0? – Struts 2.0 Framework

JavaBeat

Copyright © by JavaBeat · All rights reserved
Privacy Policy | Contact