Get going with mongoose: A beginners Guide

Keywords: RESTful API, Backend, Express, Mongoose, MongoDB

I can’t pretend that this article will be useful for everyone, but if you’re like me, a relative beginner, looking to set up a database layer for an application — and you’re wanting to build out a RESTful API with Express.js and mongoose/mongoDB — then keep reading because this article is for you.

It’s a simple guide to get you going with mongoose that should help you get through the basic installation process up to the point of setting up some persistence code for your front end (Basic ‘get’/retrieve and ‘post’/create information to and from your database). Hopefully by then you’ll feel like you know enough to keep going, but don’t worry — I’ll also drop in a few links to other relevant resources if you want to read up on some of the concepts. So let’s get going.

Get Going: A new project with Express, mongoose installed

Pre-requisites: You should already have node and npm installed. You should also know basic *nix commands (I’m using a mac).

I originally thought it would be easier to use the express generator — however we don’t need to generate views and templates because we are creating an API, so actually, let’s steer clear of that for now. Keep in mind that we are making a RESTful API (which basically means that we are only creating HTTP endpoints, such as for get and post HTTP requests) For an API like this, all of the templating will be done in a front end project, for example, with Angular. We won’t be sending any HTML, just JSON data.

Open up your console, find a suitable location and create a new directory for your app. We’ll be using an MVC structure (although we won’t really have a ‘View’, we’ll have routes).

Then set up the project:

$ mkdir getGoingApp
$ cd getGoingApp
$ mkdir controllers
$ touch controllers/dataController.js
$ mkdir models
$ touch models/data.js
$ mkdir routes
$ touch routes/api.js
$ touch app.js

Now that our directory structure is set up we’ll also want to set up the project and install our dependencies.

$ npm init

Npm init will set up a package.json file. You can leave some fields blank as it will ask you a few set up details. Make sure you set the entry point for app.js however, as this will be our server file and entry point for the application.

Next up let’s install our dependencies.

$ npm install mongoose --save
$ npm install express --save
$ npm install body-parser-json --save
$ npm install

The last step will install all other core node modules.

Now we should have pretty much everything we need in terms of structure.

Let’s set up our model first, then we’ll set up the controller and lastly the route.

getGoingApp/model/data.js:

// Require Mongoose
var mongoose = require('mongoose');

// Define a schema
var Schema = mongoose.Schema;

var dataModelSchema = new Schema({
dataName: String,
description: String
});
// Export model from schema
var Data = mongoose.model('dataModel', dataModelSchema);
module.exports = Data;

So we’re using mongoose to set up out model, which basically entails creating a model and then exporting it. You can read more about schema’s from the mongoose documentation here.

Next we want to set up a controller.

getGoingApp/controllers/dataController.js:

/*
This controller handles the callback functions for data
as will be defined in routes/api.js
*/

// We need to import the data model from out previous file
var Data = require('../models/data');

// Handle Data creation from HTTP POST - .save() is from mongoose
exports.data_create = function (req, res) {
var data = new Data(req.body);
data.save(function (err, createdData) {
if (err) {
// return error
res.status(500).send(err)
} else {
res.send(createdData);
}
})
}

// Handle Data read from GET - find() is a mongoose function
exports.data_read = function (req, res) {
Data.find({}, function (err, data){
if(err){
// return error
res.status(500).send(err)
} else {
// return array of data
res.send(data);
}
});
}

So we are exporting two functions from this file, one caller data_create and one called data_read. We will call these functions from the route that we will define in routes/index.js. Within each exported function you will see we use two parameters (req, res) so we are effectively dealing with the HTTP request and response in this file here. The .save and .find methods are provided by mongoose and will take care of accessing the data from mongoDB (once we set it up of course). You’ll notice that in both cases we are sending data (which will be useful for when we test it out) but in reality you don’t need to send data back for the .data_create function. Perhaps it’s ok just to respond with a HTTP 200 OK status.

Next up, let’s set up our routes which will call our controller from the routes/api.js file.

getGoingApp/routes/api.js:

const express = require('express');
const dataController = require('../controllers/dataController');

const router = express.Router();

// GET data
router.get('/data', dataController.data_read);

// POST data
router.post('/data', dataController.data_create);

module.exports = router;

So it’s the dataController which is actually handling/responding to the request. You can see here that the routes just call the dataController functions in response to a HTTP verb (get, post).

A good explanation of how it works can be explained in the following diagram which you can read more about in Mozilla’s tutorial here. Again, just bear in mind that we are not rendering views — which is something the Mozilla tutorial deals with.

So as you can see we are still missing an important component. Before we can use any of this code that we have written we’ll need to set up a database with mongoDB.

Depending on your operating system you might want to follow the link to your OS instructions from mongoDB here. I’m using a mac so my install looks something like this.

$ brew install mongodb
$ mkdir -p /data/db
$ sudo chmod 0755 /data/db && sudo chown $USER /data/db

First I installed mongodb, then made a data directory in the default location, then make sure that the permissions were correct. Once that’s all good, you can just run mongoDB with the following command.

mongod

So we’re nearly there. But we haven’t actually put anything in our main express file, which is app.js. We’ve kind of been working backwards this whole time, but I hope you can bear with me because we’ll have something up and running very soon.

getGoingApp/app.js:

// Get dependencies
var express = require('express');
var path = require('path');
var bodyParser = require('body-parser-json');
const http = require('http'); //ADDED IN!!!!!

// Get our API routes
const api = require('./routes/api');
const app = express();

// Set up mongoose/mongoDB connection
const mongoose = require('mongoose');
const mongoDB = 'mongodb://127.0.0.1:27017';
mongoose.connect(mongoDB);
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));

// Parsers for POST data
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

app.use('/api', api);

// Homepage route
app.get('/', function(req, res) {
res.send("welcome");
});

// Catch all other routes and return the index file
app.get('*', (req, res) => {
res.send("welcome");
});

//Get port from environment and store in Express.
const port = process.env.PORT || '3000';
app.set('port', port);

//Create HTTP server.
const server = http.createServer(app);

//Listen on provided port, on all network interfaces.
server.listen(port, () => console.log(`API running on localhost:${port}`));

So we’ve added a homepage route in here, but we’ll just use that for testing purposes.

You can now run the project from app.js

$ node app.js

Now we want to know if it’s actually working. Maybe you have checked localhost and can see ‘welcome’ but what about the API?

Postman is a cool tool which you can use to test APIs. You can also download postman here. Just start up the app and create a GET request to where your server is running which in my case is http://localhost:3000. If you see ‘welcome’ then it’s up and running and it’s time to test out the API. Make a GET request to http://localhost:3000/api/data. You should see nothing initially, because we haven’t sent/saved anything to the database yet. So let’s do that now.

Create a POST request to http://localhost:3000/api/data

Add the Header Key : Content-Type and Value: application/json. Then add the following json data for the body.

{
"dataName": "Some test data",
"description": "Some test application data"
}

Send it via the send button in Postman, then make another GET request to see your data. Make the GET request to the same location http://localhost:3000/api/data.

You should be able to shut down your node server and start it up again and see that your data persists to mongoDB if you make another GET request on start up.

And that’s it! Hopefully you found this article helpful, let me know what you think. Thanks.