Sign Ahead

RESTful people – NodeJS and MongoDB

Today, I wanted to go through the process of creating a simple API that gets data from a MongoDB using NodeJS. We’re going to use the default Mongo driver to do this. (Most use Mongoose; it is a bit easier to work with according to the internet.) We are also going to use Assert and Express.

We’re also going to use Mockaroo to get data that we can put into our MongoDB. I grabbed 1,000 rows of JSON data with the following fields: id, first_name, last_name, gender, email, and ip_address. No blanks. I saved the file to my desktop, so that’s going to be my point of reference for the commands I’m going to show you which will import the data.

My main assumption here is that you have MongoDB already installed. If you don’t, please refer to the manual and install it. Once you have it installed, you’ll need to start it.

cd c:\program files\mongodb\server\3.2\bin

mongo

show dbs

We’re going to name our DB ‘Users’ and our Collection ‘UserInformation’. We want to get the data from our JSON file on the desktop into the database. Open a new CMD window, and type the following:

cd c:\program files\mongodb\server\3.2\bin

mongoimport --db Users --collection UserInformation c:\users\user\downloads\mock_data.json --jsonArray

A few things going on here – we’re using the mongoimport.exe to import data from a file. There are a few parameters you’ll need to understand from that string; I’ve listed them below.

--db {DatabaseName} The name of the Database. If the DB doesn't exist, MongoDB will create it.

--collection {CollectionName} The name of the Collection. If it doesn't exist, MongoDB will create it.

{location of file} Where the file is located at on your computer.

--jsonArray - Tells mongo that the data is JSON.

Once you’ve done that, you’ve got data in the database. You can confirm this by going back to our original cmd window and typing the following:

a. use Users

db.UserInformation.find({"first_name" : "David"}).pretty()

You may have to substitute David for a different name; it depends on your random data. Mine, for example, does not have anyone by the name of “Greg” in it. It does, however, have 5 by the name of “Gregory”. A telling limit – find({}) searches for exactly what’s in the object.

So we’ve got data in our database; now we need to deal with making sure Mongo is running in the background. For me, I have my data folder in C:\Data, so we’ll run the mongod server using this command:

cd c:\program files\mongodb\server\3.2\bin

mongod --dbpath c:\data

And that will send a wide splash of data across the cmd window. The last line should say something like, “waiting for connections on port 27017 – and that lets us know that MongoDB is ready to be used. You can minimize the command prompt and open up your text editor – we’re ready to start writing our API.

Now, we want to define what calls we want to make first.

GET: /first/:name
GET: /last/:name
GET: /gender/:gender
GET: /ID/:id

That should be enough to get us started. Lets get the global variables out of the way first.

var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017/Users';
var express = require('express');
var app = express();

MongoClient uses the default mongodb driver; it’s how we’re going to call the database.

The URL variable is going to tell our MongoClient where our database is located. The /Users portion tells it which database to connect to.

Express, of course, handles the server stuff for us.

Now, here’s where a bit of planning is required. The calls we’re going to make are asynchronous calls, so we want to make sure we’re not trying to do something with data before we get our data back. To that end, we’re going to have to plan to pass our response through to our final method. Lets start with our actual call to the database to find information.

var queryDatabase = function(db, query, res) {
  db.collection('UserInformation').find(query).toArray(function(err, docs) {
    docs.forEach(function(doc){
      res.write(JSON.stringify(doc));
    });
    res.end();
    callback();
  });
};

var queryDatabase is a function that takes a db call, query, response, and has a callback.

The first thing we do is use db.collection to set the collection we want to use. That’s going to be ‘UserInformation’. Then we’re going to use “find()” and pass it an object. That object is our query; it is a json object that defines what we’re looking for. We did the same thing in CMD earlier when we were looking up names.

We then call “ToArray()” as it consumes something called the “Cursor”, and allows us to easily/quickly iterate through the remaining information. We create a function in there, where we have “err” and “docs”. Err is there for error handling, and docs are what we will get from the Database. And we will iterate through them using docs.forEach(). We’ve got a simple function in there that checks for each doc in docs, and writes it to our body. (That’s what res.write() does.) We use JSON.stringify() on the doc because res.write() needs a string to write to the body.

We then call res.end() to write the data to the database, and then we use our callback.

But where does that callback go?

var getDataFromMongoDB = function(query, res) {
  MongoClient.connect(url, function(err, db) {
    queryDatabase(db, query, res, function() {
      db.close();
    });
  });
};

We call queryDatabase from within getDataFromMongoDB.  This is a function that also takes a query and a res, (which we will create/supply when we actually create the URL portion of the API.) The first thing we do is set up our variable as a function taking query and res, the we connect to MonoDB using MongoClient. The connect function takes the URL (supplied earlier) and a callback function. That function will have an err, and a db for us that we can use to get data out of the database.

We’re passing the db, query, and res through to queryDatabase, and then we’ve built a function (this is where the callback is used) that closes the DB out after we’ve sent our data to the browser. So we’re making sure that the database doesn’t stay open.

Just two pieces left, now.

app.get('/first/:name', function(req, res) {
  var query = { 'first_name' : req.params.name };
  getDataFromMongoDB(query, res);
});

app.get('/last/:name', function(req, res) {
  var query = { 'last_name' : req.params.name };
  getDataFromMongoDB(query, res);
});

app.get('/gender/:gender', function(req, res){
  var query = {'gender' : req.params.gender };
  getDataFromMongoDB(query, res);
});

app.get('/ID/:id', function(req, res) {
  var query = { "id" : parseInt(req.params.id) };
  getDataFromMongoDB(query, res);
});

These are our API calls. Express sets each of these up to a URL call, taking in a parameter. We then build our query string, (basic – we want to match our parameter to a field) and then we pass that, and the response item through to open our database connection, and then query it.

And finally, we have to tell our server to listen to a port, and that’s as easy as doing this:

var server = app.listen(3000, 'localhost', function() {
  var host = server.address().address;
  var port = server.address().port;
  console.log("Listening at http://%s:%s", host, port);
});

 

spacer

One comment on “RESTful people – NodeJS and MongoDB

  1. Pingback: Employee Website – a NodeJS example – Entwined Studios

Leave a reply