Build a REST API with Node.js, Express, and MongoDB

[ SOURCE CODE ]

In this tutorial you’ll learn how to build a REST API using a Node.js server and MongoDB database. We’ll keep things simple and be building a “school” database that stores “student” records. Once you grasp the basic concepts used here you’ll be well on the way to creating more complex API based applications.

NOTE: You’ll need to install Node.js and MongoDB before proceeding.

Let’s start by creating a folder and initiating the project with the following commands:

mkdir school
cd school
npm init -y

We can now install the required dependencies using NPM:

npm install express mongoose body-parser
  • express – Provides HTTP utility methods and routes to the different API endpoints.
  • mongoose – Provides a straight-forward, schema-based solution to model application data.
  • body-parser – Parse incoming request’s in a middleware before the handlers.

Next in the index.js file lets start by including the dependences we just installed:

const express = require("express");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");

Then initiate express() and set bodyParser to use JSON:

const app = express();
app.use(bodyParser.json());

We’ll be using mongoose to connect to the “school” database. This database doesn’t need to exist yet as it’ll be automatically created when the first student record is added:

const db = "mongodb://localhost/school";
mongoose
  .connect(db, { useNewUrlParser: true, useUnifiedTopology: true })
  .then(() => console.log("MongoDB Connected"))
  .catch((err) => console.log(err));

Finally tell the app to listen on port 5000 and log a message when the server is running:

app.listen(5000, () => console.log("Server Running"));

You can now start the server by running the following command:

node index.js

If successful you’ll see “MongoDB Connected” & “Server Running” logged in the terminal.

We’ll also install nodemon which monitors for file changes and automatically restarts the server so you don’t have to do it manually each time:

npm install nodemon --save-dev
nodemon index.js

Creating the model

Models are responsible for creating and reading documents from the MongoDB database.

Create a new folder called models and inside add a student.js file with the following:

const mongoose = require("mongoose");
const Schema = mongoose.Schema;

const StudentSchema = new Schema({
  name: { type: String, required: true },
  age: { type: Number, required: true },
  email: { type: String, required: true },
});

module.exports = mongoose.model("student", StudentSchema);

This defines our schema (name, age, and email) in a student collection.

Creating the routes

Routes tell the application what code to execute when a specific URL (route) is requested.

Let’s start with the router that will add new student records to the database. Create a new folder called routes and inside add a student.js file with the following:

const express = require("express");
const router = express.Router();
const Student = require("../models/student");

router.post("/add", (req, res) => {
  const newStudent = new Student({
    name: req.body.name,
    age: req.body.age,
    email: req.body.email,
  });
  newStudent
    .save()
    .then(() => res.json("Student Added..."))
    .catch((err) => res.status(400).json("Error: " + err));
});

module.exports = router;

We then need to include the router the index.js file using the following:

const studentsRouter = require("./routes/student");
app.use("/students", studentsRouter);

Before creating the other endpoints let’s test that everything is working using Insomnia a free desktop API client (Windows & OSX). Once installed create a “New Request” with the following settings:

Alt Text

Send the request to http://localhost:5000/students/add with the following JSON data:

Alt Text

If successful you’ll see the “Student Added” message.

You can then use MongoDB Compass to visualise the database:

Alt Text

With the /add endpoint working let's proceed with creating the other routes.

All of the route’s should be added to the routes/student.js file.

First a GET request that returns all students in JSON format:

// http://localhost:5000/students/ 
router.get("/", (req, res) => {
  Student.find()
    .then((students) => res.json(students))
    .catch((err) => res.status(400).json("Error: " + err));
});

Next delete a student record that has the matching _id:

// http://localhost:5000/students/delete/STUDENT_ID
router.delete("/delete/:id", (req, res) => {
  Student.findByIdAndDelete(req.params.id)
    .then(() => res.json("Student Deleted..."))
    .catch((err) => res.status(400).json("Error: " + err));
});

Finally update a student record with the matching _id:

// http://localhost:5000/students/update/STUDENT_ID
router.post("/update/:id", (req, res) => {
  Student.findById(req.params.id)
    .then((student) => {
      student.name = req.body.name;
      student.age = req.body.age;
      student.email = req.body.email;
      student
        .save()
        .then(() => res.json("Student Updated..."))
        .catch((err) => res.status(400).json("Error: " + err));
    })
    .catch((err) => res.status(400).json("Error: " + err));
});

When updating a student you also need to pass the updated JSON data:

{
  "name" : "Amanda Jane Burns",
  "age" : "14",
  "email" : "amanda.burns@gmail.com"
}

That completes the API setup, thanks for reading!