Building a RESTfull API with Node.js and Express

Building a RESTfull API with Node.js and Express

Check out the source code here

And Video *PlayList*

*Representational state transfer (REST) or [RESTful](en.wikipedia.org/wiki/Representational_stat..) [Web services](en.wikipedia.org/wiki/Web_service) are one way of providing interoperability between computer systems on the internet. REST-compliant Web services allow requesting systems to access and manipulate textual representations of [Web resources](en.wikipedia.org/wiki/Web_resource) using a uniform and predefined set of [stateless](en.wikipedia.org/wiki/Stateless_protocol) operations. Other forms of Web service exist, which expose their own arbitrary sets of operations such as [WSDL](en.wikipedia.org/wiki/WSDL) and [SOAP](en.wikipedia.org/wiki/SOAP)*.

GRAB BOILERPLATE

We won’t repeat all the basic codes over and over. For our purpose this boilerplate is enough. Make a directory and pull the *git repo*.

git init
git pull [https://github.com/bmshamsnahid/NEB-Boilerplate.gi](https://github.com/bmshamsnahid/NEB-Boilerplate.git)t

If there is any question or confusing term about the boilerplate, take a look in the *article*.

INTRO

Here I create a simple contact-book. It will take the people name and their phone number. For database, I’m using mongoDB.

In database schema, we got

  • personName (Type: String)

  • personNumber (Type: String)

Generate two database:

  1. contactsBook

  2. contactsBookTest

One for storing the actual data and the next one is for testing purpose. In real world you won’t want to mess the test data with the actual data.

PRE PRODUCTION

Database

Let’s create two database

mongo
use contactsBook
use contactsBookTest

If you are not using linux, for mac you might have to traverse to the mongoDB installation folder.

Now go to the /config/index.js file and change the database name to contactsBook and contactsBookTest. Your /config/index.js file would be

**var **db = {
    **db**: **'localhost:27017/contactsBook'**,
    **dbTest**: **'localhost:27017/contactsBookTest'**,
    **mySecret**: **'Eminem'
**};

module.exports = {
    **database**: db
};

Dependency

If there is a node_modules folder already exist, I would prefer to delete the folder. It would help to keep the modules up-to-date.

Go to the project root folder and run

npm install

It will install all the dependencies described in the package.json file.

Now our application is ready to start

nodemon

You must see the following line in your console

Server running on port: 3000

Now application is ready for extends the boilerplate.

MODELS

Create a directory contacts under /app/models directory. Now under contacts directory create index.js

Now /app/models/contacts/index.js will be …

**var **mongoose = require(**'mongoose'**);
**var **Schema = mongoose.Schema;
mongoose.**Promise **= global.*Promise*;

**var **contactsSchema = **new **Schema({
    **personName**: {
        **type**: String,
        **required**: **true
    **}, **personNumber**: {
        **type**: String,
        **required**: **true
    **}
});

modules.**exports **= mongoose.**models**(**'Contact'**, contactsSchema);

Here I declare the contactSchema and two properties, personName and personNumber. Both is string type and must be required. Otherwise error will be generated.

Outsides, the module will be renamed as the Contact module.

CONTROLLER

In the /app/controllers/contacts/controller/index.js

**var **base = process.**env**.PWD;
**var **Contact = require(base + **'/app/models/contacts'**);

**var ***getContacts *= (req, res) => {
    Contact.find((err, contacts) => {
        **if**(err)  res.send(500, {**'err'**: err});
        **else **res.send(200, contacts);
    });
};

**var ***getContact *= (req, res) => {
   Contact.findById(req.params.id, (err, contact) => {
       **if**(err)  res.send(500, {**'err'**: err});
       **else **res.send(200, contact);
   });
};

**var ***createContact *= (req, res) => {
    **var **newContact = **new **Contact(req.body);
    newContact.save((err, savedContact) => {
        **if**(err) res.send(500, {**'err'**: err});
        **else **res.send(200, savedContact);
    });
};

**var ***updateContact *= (req, res) => {
  Contact.findById(req.params.id, (err, contact) => {
      **if**(err) res.send(500, {**'err'**: err});

      **if**(req.body.**personName**) contact.**personName **= req.body.**personName**;
      **if**(req.body.**personNumber**) contact.**personNumber **= req.body.**personNumber**;

      contact.save((err, updatedContact) => {
          **if**(err) res.send(500, {**'err'**: err});
          res.send(200, updatedContact);
      });
  });
};

**var ***removeContact *= (req, res) => {
    Contact.findByIdAndRemove(req.params.id, (err) => {
        **if**(err) {
            res.send(500, {
               **'success'**: **false
            **});
        } **else **{
            res.send(200, {
                **'success'**: **true
            **});
        }
    });
};

module.exports = {
    *getContact*,
    *getContacts*,
    *createContact*,
    *updateContact*,
    *removeContact
*};

ROUTING

In this REST API we describe 5 routes:

  • Get request to get all the contacts information.

  • Get request to get specific person’s contact’s information.

  • Post request to create a persons info in contacts list.

  • Put request to update a specific persons information.

  • Delete request to remove a specific persons information from the contacts list.

In /app/routes/endPoints

**var **base = process.**env**.PWD;
**var **express = require(**'express'**);
**var **router = express.Router();
**var **contactsController = require(base + **'/app/controllers/contactsController'**);

router.get(**'/contacts'**, contactsController.*getContacts*);
router.get(**'/contact/:id'**, contactsController.*getContact*);
router.**post**(**'/contact'**, contactsController.*createContact*);
router.put(**'/contact/:id'**, contactsController.*updateContact*);
router.delete(**'/contact/:id'**, contactsController.*removeContact*);

module.exports = router;

API TESTING

Create a contact:

Get a contact:

Update a contact

Get all contacts:

Delete a contact:

POST PRODUCTION

So here we are!!! REST-full api is completed. CRUD(CREATE, READ, UPDATE, DELETE) operation is completed. But one thing is, unit testing is not provided here. I will discuss about unit testing in the next article. Stay tuned and if there is a confusing term or something, response below or create an issue in *github*.