DEV Community

Michael Okoh
Michael Okoh

Posted on

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

First Published in JavaScript January

Hello there,

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();
Enter fullscreen mode Exit fullscreen mode

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');
});
Enter fullscreen mode Exit fullscreen mode

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");
});
Enter fullscreen mode Exit fullscreen mode

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');
});
Enter fullscreen mode Exit fullscreen mode

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 teir provider

step3
select a region where you want your database to be hosted, select a region close to where you live for better performance

step4
specify a name for your database, in my case i named mine crud

step5
confirm your specifications/order

step6
go to the Users tab to create a new Database user

step7
when done. the user created 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
Enter fullscreen mode Exit fullscreen mode

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
})
Enter fullscreen mode Exit fullscreen mode

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')
  })
})
Enter fullscreen mode Exit fullscreen mode

Keep these in mind

HTTP Verb     Operation
GET           Read
POST          Create
PUT           Update
DELETE        Delete
Enter fullscreen mode Exit fullscreen mode

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}));
Enter fullscreen mode Exit fullscreen mode

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');
    });
  });
Enter fullscreen mode Exit fullscreen mode

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)
    });
});
Enter fullscreen mode Exit fullscreen mode

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);
    });
 });
Enter fullscreen mode Exit fullscreen mode

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');
    });
});
Enter fullscreen mode Exit fullscreen mode

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"
    }
]
Enter fullscreen mode Exit fullscreen mode

Let's try to edit this entry:

{
    "_id": "5a52b1ee8635184cf9f7fd34",
    "first_name": "Christiano",
    "last_name": "Ronaldo"
}
Enter fullscreen mode Exit fullscreen mode

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"
    }
]
Enter fullscreen mode Exit fullscreen mode

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');
    });
 });
Enter fullscreen mode Exit fullscreen mode

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"
    }
]
Enter fullscreen mode Exit fullscreen mode

We'll delete this one:

{
    "_id": "5a52b2008635184cf9f7fd35",
    "first_name": "Adekunle",
    "last_name": "Gold"
}
Enter fullscreen mode Exit fullscreen mode

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"
    }
]
Enter fullscreen mode Exit fullscreen mode

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');
    });
  });

});
Enter fullscreen mode Exit fullscreen mode

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

Bye

Top comments (9)

Collapse
 
luucamay profile image
Lupe 🇧🇴

Thank you, amazing post!

Collapse
 
blouzada profile image
Bruno Louzada

I have a question about partial updates how do you handle that? Awesome post thanks for sharing

Collapse
 
ichtrojan profile image
Michael Okoh

Thanks, for the partial updates the $set key is supposed to take care of that

Collapse
 
sosnayak profile image
Suhas nayak

I am getting attached error in POSTMAN. Could you please help me to resolve the issue.

Collapse
 
ichtrojan profile image
Michael Okoh

Can you post the Error message?

Collapse
 
rachelwong profile image
Rachel

I had a 500 error indicating that dbase is not defined. Now I have a 400 error saying cannot get /name/add route, which is really odd.

Collapse
 
dimpiax profile image
Dmytro Pylypenko

Advertising post.

Also, how in 2018 code could be so not pretty?

Collapse
 
ichtrojan profile image
Michael Okoh

It would be, BTW check github.com/ichtrojan/essential-kit