Basic Routing, HTTP Requests, and CRUD Operations with Express and MongoDB

Basic Routing, HTTP Requests, and CRUD Operations with Express and MongoDB

Written by Michael Okoh and edited by Alan Smith

Let's talk about routes. A route is simply an entry point into your application. So we are going to build routes to perform some HTTP requests with ExpressJS.

Getting Started

First, we'll need to do some setup:

  • create a new folder and name it whatever you want: mkdir express-routes
  • change your terminal directory to that folder: cd express-routes
  • run npm init (you can press enter for all prompts).
  • install Express: npm install express --save
  • create a new file in that folder: touch index.js
  • Now open index.js in your favorite text editor, in my case Atom

Then we need to import Express into our application:

    const express = require('express');
    const app = express();

Now we have to create a server where browsers and API calls can connect. We can do that with Express' listen method:

    app.listen(3000, function() {
      console.log('listening on 3000');
    });

You can test your server by running node index.js. You should see this:

test

Adding our First Routes

Now let's create a route that we can access in the browser. Browsers only serve pages using a GET request, so we need to create a route using Express' get method like this:

    app.get('/', function(req, res) {
      res.send("Yep it's working");
    });

You'll need to restart your Node server to see this update. You can do this by typing CTRL + C to stop your server and then run node index.js. If you visit http://localhost:3000 on your web browser, you should see this:

test1

Let's add another route:

    app.get('/love', (req, res) => {
      res.send('Hi Love');
    });

If you visit http://localhost:3000/love, you should see this:

test2

You may have noticed I'm now using an arrow function, which is an ES6 feature. You can learn more about the ES6 specification here.

Now that we've learned how to create a basic route in Express, let's go further by learning CRUD operations using MongoDB. But before we move forward, aren't you tired of restarting your server every time you make a change? You can fix this problem by using a package called Nodemon.

Adding Nodemon

You can install Nodemon by running npm install nodemon --save-dev. Then edit your package.json like this:

test3

Now run npm run dev in your terminal, and you should see:

test4

Now with Nodemon set up, you won't have to restart your server whenever you make a change. However, you will need to refresh your browser to see those changes.

CRUD Operations

CRUD (create, read, update, and delete) operations are the four basic database functions. For this tutorial, we'll use a remote MongoDB service called mLab. We'll be building a simple application to store and retrieve first_name and last_name values from our database.

Setting up MongoDB and mLab

To create a new account and set up a database, you will need to go here. I've provided the images below as a reference guide on setting up your database.

step1

create a new MongoDB Depoyment

step2

select Amazon which is the free tier provider

step3

select a region where you want your database to be hosted (choose one close to where you live for better performance)

step4

specify a name for your database (I named mine "crud")

step5

confirm your specifications/order

step6

go to the Users tab to create a new Database user

step7

when you're done, the created user should pop up

mLab should give you your credentials, which can be found at the top

credentails

replace <dbuser> and <dbpassword> with the credentials of the user you just created

With our remmote database set up, we can install MongoDB in our application by running:

    npm install mongodb --save

Now let's import MongoDB into our application:

    const MongoClient = require('mongodb').MongoClient
    var ObjectID = require('mongodb').ObjectID; // we will use this later
    
    MongoClient.connect('link-to-mongodb', (err, database) => {
      // ... start the server
    })

Remember to replace link-to-mongodb with the URL mLab gave you, in my case:

   `mongodb://<dbuser>:<dbpassword>@ds247027.mlab.com:47027/crud`

Also be sure to replace <dbuser> and <dbpassword> with the credentials you created.

Now wrap the listen method within the MongoClient callback like this:

 MongoClient.connect('mongodb://trojan:00000000@ds247027.mlab.com:47027/crud', (err, db) => {
      var dbase = db.db("crud");
      if (err) return console.log(err)
      app.listen(3000, () => {
        console.log('app working on 3000')
      })
    })

Keep these in mind.

HTTP Verb   Operation
GET         Read
POST        Create
PUT         Update 
DELETE      Delete 

Earlier we learned that a browser gets pages via the GET request, but to add data to a database we will need to use the POST request. We can use a service called postman to send these requests.

For our application to receive post requests, we will need a package called body-parser, which we can install by running npm install body-parser --save. Then we can import it into our application like this:

    const express = require('express');
    const MongoClient = require('mongodb').MongoClient
    var ObjectID = require('mongodb').ObjectID;
    const bodyParser= require('body-parser')
    const app = express();
    
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({extended: true}));

Creating an Entry

We'll use the POST HTTP verb to create a new entry in our database. Let's create our post route:

    app.post('/name/add', (req, res, next) => {
    
        var name = {
          first_name: req.body.first_name,
          last_name: req.body.last_name
        };
    
        dbase.collection("name").save(name, (err, result) => {
          if(err) {
            console.log(err);
          }
    
          res.send('name added successfully');
        });
      });

To test this application:

postman

If you see name added successfully, you can check your mLab Dashboard and find a new collection called name.

mlab

And if you click on name, you will see the data you sent in your post request:

mlabs1

Reading All Entries

Now let's add a function to handle GET requests to our database in Express.

    app.get('/name', (req, res) => {
        dbase.collection('name').find().toArray( (err, results) => {
          res.send(results)
        });
    });

We can test with Postman by sending a GET request to http://localhost:300/name like this:

postman2

Reading by ID

We can also make GET requests by id which is automatically assigned to entries in our database. We can add that id to our request via the URL.

details

For example, the data we have in the image above has the id of 5a5252b2d60a9f4a4254bade. So when we pass its id in the URL like this:

url

it would return the entry associated with that id. We can add an Express handler for this type of request like this:

    app.get('/name/:id', (req, res, next) => {
        if(err) {
          throw err;
        }
    
        let id = ObjectID(req.params.id);
        dbase.collection('name').find(id).toArray( (err, result) => {
          if(err) {
            throw err;
          }
    
          res.send(result);
        });
     });

Updating by ID

We learned how to add data using a POST request and how to retrieve data using a GET request. Now we are going to add a handler to update an existing record by id using a PUT request:

    app.put('/name/update/:id', (req, res, next) => {
        let id = {
          _id: ObjectID(req.params.id)
        };
    
        dbase.collection("name").update({_id: id}, {$set:{'first_name': req.body.first_name, 'last_name': req.body.last_name}}, (err, result) => {
          if(err) {
            throw err;
          }
          res.send('user updated sucessfully');
        });
    });

We can test this using Postman. I added more data, as you can see in the image below:

getall

    [
        {
            "_id": "5a52a2a314622d0c85d8da3f",
            "first_name": "Thomas",
            "last_name": "Okoh"
        },
        {
            "_id": "5a52b1dc8635184cf9f7fd32",
            "first_name": "Kun",
            "last_name": "Aguero"
        },
        {
            "_id": "5a52b1e48635184cf9f7fd33",
            "first_name": "Ed",
            "last_name": "Sheeran"
        },
        {
            "_id": "5a52b1ee8635184cf9f7fd34",
            "first_name": "Christiano",
            "last_name": "Ronaldo"
        },
        {
            "_id": "5a52b2008635184cf9f7fd35",
            "first_name": "Adekunle",
            "last_name": "Gold"
        }
    ]

Let's try to edit this entry:

    {
        "_id": "5a52b1ee8635184cf9f7fd34",
        "first_name": "Christiano",
        "last_name": "Ronaldo"
    }

We'll use a PUT method in Postman to update last_name from Ronaldo to Messi and first_name from Christiano to Lionel using the id: 5a52b1ee8635184cf9f7fd34.

PM

When we check the entries in our database, we see they have been updated.

    [
        {
            "_id": "5a52a2a314622d0c85d8da3f",
            "first_name": "Thomas",
            "last_name": "Okoh"
        },
        {
            "_id": "5a52b1dc8635184cf9f7fd32",
            "first_name": "Kun",
            "last_name": "Aguero"
        },
        {
            "_id": "5a52b1e48635184cf9f7fd33",
            "first_name": "Ed",
            "last_name": "Sheeran"
        },
        {
            "_id": "5a52b1ee8635184cf9f7fd34",
            "first_name": "Messi",
            "last_name": "Lionel"
        },
        {
            "_id": "5a52b2008635184cf9f7fd35",
            "first_name": "Adekunle",
            "last_name": "Gold"
        }
    ]

Deleting by ID

Finally, we've arrived at the last phase of this application: deleting entries by id. We will do this by using the DELETE request. Let's create a handler function in our application.

    app.delete('/name/delete/:id', (req, res, next) => {
        let id = ObjectID(req.params.id);
    
        dbase.collection('name').deleteOne(id, (err, result) => {
          if(err) {
            throw err;
          }
    
          res.send('user deleted');
        });
     });

Let's review our current entries:

    [
        {
            "_id": "5a52a2a314622d0c85d8da3f",
            "first_name": "Thomas",
            "last_name": "Okoh"
        },
        {
            "_id": "5a52b1dc8635184cf9f7fd32",
            "first_name": "Kun",
            "last_name": "Aguero"
        },
        {
            "_id": "5a52b1e48635184cf9f7fd33",
            "first_name": "Ed",
            "last_name": "Sheeran"
        },
        {
            "_id": "5a52b1ee8635184cf9f7fd34",
            "first_name": "Messi",
            "last_name": "Lionel"
        },
        {
            "_id": "5a52b2008635184cf9f7fd35",
            "first_name": "Adekunle",
            "last_name": "Gold"
        }
    ]

We'll delete this one:

    {
        "_id": "5a52b2008635184cf9f7fd35",
        "first_name": "Adekunle",
        "last_name": "Gold"
    }

We'll make our DELETE request via Postman:

firepost

Success!!!

    [
        {
            "_id": "5a52a2a314622d0c85d8da3f",
            "first_name": "Thomas",
            "last_name": "Okoh"
        },
        {
            "_id": "5a52b1dc8635184cf9f7fd32",
            "first_name": "Kun",
            "last_name": "Aguero"
        },
        {
            "_id": "5a52b1e48635184cf9f7fd33",
            "first_name": "Ed",
            "last_name": "Sheeran"
        },
        {
            "_id": "5a52b1ee8635184cf9f7fd34",
            "first_name": "Messi",
            "last_name": "Lionel"
        }
    ]

Our entry has been deleted.

Conclusion

At this point, your index.js should look like this:

    const express = require('express');
    const MongoClient = require('mongodb').MongoClient
    const bodyParser= require('body-parser')
    var ObjectID = require('mongodb').ObjectID;
    const app = express();
    
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({extended: true}));
    
    MongoClient.connect('mongodb://trojan:00000000@ds247027.mlab.com:47027/crud', (err, db) => {
      if (err) return console.log(err)
    
      app.listen(3000, () => {
        console.log('app working on 3000')
      });
    
      let dbase = db.db("crud");
    
      app.post('/name/add', (req, res, next) => {
    
        let name = {
          first_name: req.body.first_name,
          last_name: req.body.last_name
        };
    
        dbase.collection("name").save(name, (err, result) => {
          if(err) {
            console.log(err);
          }
    
          res.send('name added successfully');
        });
    
      });
    
      app.get('/name', (req, res, next) => {
        dbase.collection('name').find().toArray( (err, results) => {
          res.send(results)
        });
      });
    
      app.get('/name/:id', (req, res, next) => {
        if(err) {
          throw err;
        }
    
        let id = ObjectID(req.params.id);
        dbase.collection('name').find(id).toArray( (err, result) => {
          if(err) {
            throw err;
          }
    
          res.send(result);
        });
      });
    
      app.put('/name/update/:id', (req, res, next) => {
        var id = {
          _id: new ObjectID(req.params.id)
        };
    
        dbase.collection("name").update(id, {$set:{first_name: req.body.first_name, last_name: req.body.last_name}}, (err, result) => {
          if(err) {
            throw err;
          }
    
          res.send('user updated sucessfully');
        });
      });
    
    
      app.delete('/name/delete/:id', (req, res, next) => {
        let id = ObjectID(req.params.id);
    
        dbase.collection('name').deleteOne({_id: id}, (err, result) => {
          if(err) {
            throw err;
          }
    
          res.send('user deleted');
        });
      });
    
    });

All done. If you followed this article to this point, you should be very proud of yourself. Go forth and build for the next billion users.

You can always reach out to me on Twitter.

Reduce, Reuse, React

Reduce, Reuse, React

An Introduction to Async / Await

An Introduction to Async / Await