Create a REST API with Node.js, Express, and MongoDB
Creating a REST API with Node.js is simple, fast, and efficient. Node.js is lightweight, non-blocking, and perfect for data-intensive applications. Node.js, although young, has a strong community backing. The Node.js community provides a vast array of modules that can be leveraged to simplify the implementation process. Node.js also has support for many widely used offerings. In this post, we will use MongoDB with Node.js. We will also use two modules, Express, and Monk. After you have made your API, you will need to run api testing to be assured that it will work within the setting it is made for.
Let’s briefly explain each of these components:
- Node.js – a lightweight platform built on Chrome’s JavaScript runtime for easily building fast, scalable network applications.
- MongoDb – is an open-source document database, and the leading NoSQL database.
- Express.js – a web application framework for Node
- Monk – a tiny layer that provides simple yet substantial usability improvements for MongoDB usage within Node.js
I. Prerequisites:
- A basic understanding of RESTful design principles.
- Install Node.js – see nodejs.org and click Install.
- Install MongoDb – see MongoDb.org
- Install Express.js globally –
npm express -g
- (Install Node.js packages for Express, Monk and Mongo DB – Don’t worry about this now, I’ll explain below)
Let’s now create a REST API that enables us to maintain a database of cars.
II. Create a Node.js / Express project
In the prerequisites section, we installed Express.js. To do so, we ran
npm express -g
This installs express globally and provides us with a new express
binary installed in NODE_HOME/bin
directory.
We now use express
to create our project:
express cars_project
This creates a new directory, cars_project, that contains our project files. app.js
is our project’s entry point
Since we plan to use Monk and MongoDB, we must add them as dependencies.
To add the dependent modules, edit the package.json
file located in the cars_project
directory and add monk and mongodb to the dependencies list:
[code language=”JavaScript”]
{
“name”: “cars-project”,
“version”: “0.0.1”,
“private”: true,
“scripts”: {
“start”: “node app.js”
},
“dependencies”: {
“express”: “3.5.1”,
“mongodb”:”*”,
“monk”:”*”
}
}
[/code]
Finally, we must install all dependent modules into our local project.
To do so, navigate to the cars_project
directory and run:
npm install
III. Test our server
cars-project/app.js is our project entry point. app.js provides the logic to start our web server. Yes, you heard the correctly, app.js implements the http server, which means we do not need a third party web server. If we were to need a third party web server, a dedicated server would provide the most power, compared with a shared server. You can click here to check out different servers dedicated for you if you are interested in using a dedicated server for your website.
Also, Node.js creates our web server in just a few lines of code. Wow!
[code language=”JavaScript”]
http.createServer(app).listen(app.get(‘port’), function(){
console.log(‘Express server listening on port ‘ + app.get(‘port’));
});
[/code]
Let’s start our application and test it!
node app.js
Point your browser to http://localhost:3000, you should see the Express welcome page.
If you are curious as to how that is rendered, browse the app.js code
IV. Define the REST API
(For a detailed explanation of REST. See my post on RESTful Design principles)
GET | /cars | Get a list of all cars |
GET | /cars/ |
Get the car identified by |
POST | /cars | Create a new car |
PUT | /cars/ |
Update the car identified by |
DELETE | /cars/ |
Delete the car identified by |
IV. Implement/Stub the REST API using Node.js/Express.js
To start, lets create a new JavaScript file to handle the requests to our car resource. This file will be responsible for handling the requests described in the table above. For example, this file will handle GET /cars
, GET /cars/
, POST /cars
, etc.
Create a folder cars_project/resources
to contain our new file carres.js
.
For now carres.js should export the following stubbed out public functions:
[code language=”JavaScript”]
exports.findAll = function(req, res) {
// logic to handle GET /cars
};
exports.findById = function(req, res) {
// logic to handle GET /cars/
};
exports.create = function(req, res) {
// logic to handle POST /cars
}
exports.create = function(req, res) {
// logic to handle PUT /cars/
}
exports.deleteById = function(req, res) {
// logic to handle DELETE /cars/
}
[/code]
Now that we have our basic handlers, lets wire them up in app.js
.
We can define this just above the http server code
[code language=”JavaScript”]
// Car resource routes
var carResource = require(‘./resource/carres’);
app.get(‘/cars’, carResource.findAll);
app.get(‘/cars/:id’, carResource.findById);
app.post(‘/cars’, carResource.create);
app.delete(‘/cars/:id’, carResource.removeById);
app.put(‘/cars/:id’, carResource.update);
http.createServer(app).listen(app.get(‘port’), function(){
console.log(‘Express server listening on port ‘ + app.get(‘port’));
});
[/code]
We have now implemented the basic structure for our REST API.
We can test it, however none of our REST operations return a response.
Let’s quickly write some code to return a 201
status when we POST /cars
In carsres.js, implement the following:
[code language=”JavaScript”]
exports.create = function(req, res) {
// For testing purposes, we are not actually creating anything
res.send(201); // created
};
[/code]
Okay, now lets validate that our API is indeed operational.
First, we must start our web server
cd cars_project node app.js
Next, using curl, let’s formulate a POST
request and validate we get a 201
in response:
curl -X -i POST http://localhost:3000/cars
Verify the 201
status response
V. Create a model object to persist and retrieve Cars to and from MongoDB
Let’s create a new folder cars_project/model
and a new file cars.js.
The following JavaScript file manipulates our MongoDB. Here we perform our CRUD operations: Create, Retrieve, Update, and Delete.
Please see the code comments included below for a detailed explanation of carres.js
.
[code language=”JavaScript”]
// export this module, so that it is accessible to our application modules
module.exports = Cars;
// Cars constructor
function Cars() {
if (!(this instanceof Cars)) {
return new Cars();
}
// require mongodb
var mongo = require(‘mongodb’);
// Connect to our mongodb running on localhost and named ‘test’
var db = require(‘monk’)(‘localhost/test’);
// obtain a reference to our cars collection within mongodb
this.cars = db.get(‘cars’);
};
// Retrieve a list of all persisted
Cars.prototype.findAll = function(success, error) {
this.cars.find({},{},response(success, error));
};
// Retrieve a car by its id
Cars.prototype.findById = function(id, success, error) {
this.cars.findById(id, response(success,error));
};
// Persist a new car document to mongodb
Cars.prototype.create = function(car, success, error) {
this.cars.insert(car, response(success,error));
};
// Update an existing car document by id in mongodb
Cars.prototype.update = function(car, success, error) {
this.cars.findAndModify(car._id,
{ $set: { name: car.name } }, response(success, error));
};
// Remove a car by id from the mongodb
Cars.prototype.removeById = function(id, success, error) {
this.cars.remove({_id : id}, response(success, error));
};
// Callback to the supplied success and error functions
// The caller will supply this function. The callers implementation
// will provide the necessary logic. In the case of the sample app,
// the caller’s implementation will send an appropriate http response.
var response = function(success, error) {
return function(err, doc) {
if (err) {
// an error occurred, call the supplied error function
error(err);
} else {
// call the supplied success function
success(doc);
}
};
}
[/code]
VI. Wiring the cars model and cars resource
Now that we’ve created a model object for cars, we must update our cars resource such that it can make the appropriate model calls to manipulate documents stored in MongoDB.
Open resources/carsres.js, and make the following modifications:
[code language=”JavaScript”]
var cars = require(‘../db/cars’)();
exports.findAll = function(req, res) {
var ok = function(doc) {
res.json(doc);
};
var err = function(err) {
res.send(404);
};
cars.findAll(ok, err);
};
exports.findById = function(req, res) {
var ok = function(doc) {
res.json(doc);
};
var err = function(err) {
res.send(404);
};
cars.findById(req.params.id, ok, err);
};
exports.create = function(req, res) {
var ok = function(doc) {
res.location(‘/cars/doc._id’);
res.send(201);
};
var err = function(err) {
res.send(409, “Failed to create car”);
};
cars.create(req.body, ok, err);
};
exports.update = function(req, res) {
if (!req.body._id) {
res.send(404, “id required”);
} else {
var ok = function(doc) {
res.send(200);
};
var err = function(err) {
res.send(409, “update failed”);
};
cars.update(req.body, ok, err);
}
};
exports.removeById = function(req, res) {
var ok = function(doc) {
res.send(200);
};
var err = function(err) {
res.send(409, “Failed to remove car”);
};
cars.removeById(req.params.id, ok, err);
[/code]
VII. Conclusion
There you have it, a fully operational RESTful API that persists information to a MongoDB. All of this with minimal code. Cool! Node.js is quite amazing and quite powerful. Impressive!
Thank you!
1 Response
[…] Source: Create a REST API with Node.js, Express, and MongoDB | c m d […]