CRUD operations with REST API

This exercise demonstrates CRUD operation with REST API for previously created routes

 

Objective

Create functional REST API endpoints (CRUD Operations) for customer resource

Description

In our previous exercise, we created routes, built Mongoose schema, and connected to Mongo DB. In this exercise, we will combine everything and make the routes functional to do CRUD operations.

Acceptance Criteria

  • POST requests should add a new customer to the database.
  • GET request should show the list of all the customers in the database
  • GET request with an id as a route parameter should return the information of the respective customer.
  • PATCH request with an id as a route parameter should update the customer’s information
  • Delete request an id as a route parameter should delete the customer from the database.

Hints

  • Install and use body-parser middleware. This middleware reads a form’s input and stores it as a javascript object that can be accessed through req.body

npm i body-parser

// Require body-parser
const bodyParser = require("body-parser");

// use body-parser middleware
app.use(bodyParser.json());

 

  • Connect to Mongo DB using:
mongoose.connect(MONGO_URI, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

 

  • Require the Customer Schema from the Models directory in index.js
const Customer = require("./models/customer");

 

  • Use next() middleware to pass control to the next middleware function if the current middleware function does not end the request-response cycle

  • Use .find() .exec() to query the database for GET request.

  • Use .create() with POST to create new customer

  • Use findById(id).exec() to find the customer with the id specified

  • Use findByIdAndRemove() to delete a customer

  • Use findByIdAndUpdate() to update the customer

  • The above methods will create a promise. Use then() to handle the completed promise to send the response.

  • Handle errors using a catch block.

 

Solution

 

We will begin by installing body-parser middleware in our project.

npm i body-parser

This middleware is necessary in express.js because it parses the HTTP POST request’s body into a javascript object that can be accessed through req.body

Next, require and use this middleware in our index.js file.

// Require body-parser
const bodyParser = require("body-parser");

// use body-parser middleware
app.use(bodyParser.json());

Require the Customer model that was defined in models/customer.js in our index.js file. const Customer = require('./models/customer')

Creating a POST route

The following code creates an endpoint that will listen to the HTTP POST request. This route will expect the POST data through req.body and it this data will be inserted as a new entry (document) in the database.

app.post("/", function(req, res, next) {
  Customer.create(req.body)
    .then((customer) => {
      res.json({
        message: "New customer added",
        customerCreated: customer,
      });
    })
    .catch((error) => {
      res.json({ error });
    });
});

The above route uses Model.create(data) function of Mongoose to insert a new document into the database. Here, Customer is the Model which was defined and imported from models/customer.js.
The data or the document to be inserted to the database as received through req.body parameter.

The next middleware is used to pass control to the next middleware function if the current middleware function does not end the request-response cycle.

If the request is successful, it responds with a message New customer added and also shows the information of the customer added.

We can use Postman to test this route and also enter a mock customer into our database. Select the POST method and enter the endpoint “http://localhost:9001”

Set the headers as Content-type: application/json and enter this mock data as body (raw – json):

{
  "first_name": "John",
  "last_name": "Doe",
  "email": "john.doe@gamil.co",
  "phone": 636387483,
  "verified_email": true,
  "address": {
    "street": "400S 100E",
    "city": "Santa Barbara",
    "zip": "83938",
    "country": "US"
  }
}

Request and Response for POST in postman

Request and Response for POST in postman

You can also verify that the document was inserted by logging into your MongoDB atlas account and checking your collections data.

Document inserted in MongoDB atlas

Document inserted in MongoDB atlas using CRUD Operation

Similarly, you can go ahead and create a few more customers.

Finding a customer from database

//Find customer by ID

app.get("/:id", (req, res, next) => {
  const id = req.params.id;

  Customer.findById(id)
    .exec()
    .then((customer) => {
      if (customer) {
        res.json(customer);
      } else {
        res.json({
          message: "No customer found with the provided id.",
        });
      }
    })

    .catch((error) => {
      res.json({ error });
    });
});

This endpoint will listen for the GET request at the / route and with a route parameter. Here, id ,which is the unique id of the customer stored in the database, is passed to the end point as a route parameter. This id is used to find a customer from the database.

findById method is used to find the customer from the database.

For example, the id for the customer “John Doe” that we had created is 602773db484c00004b966255. Now pass this id to the endpoint “http://localhost:9001/602773db484c00004b966255” and do a GET request in Postman.

GET specific customer – Postman

GET specific customer - Postman

To get all customers from the database we can chain find() and exec() functions.

app.get("/", (req, res, next) => {
  Customer.find()
    .exec()
    .then((docs) => {
      res.json(docs);
    })
    .catch((error) => {
      res.json({ error });
    });
});

Updating a customer

We will create a PATCH endpoint to update a customer’s information from the database.

//Update a customer
app.patch("/:id", (req, res, next) => {
  const id = req.params.id;
  Customer.findByIdAndUpdate({ _id: id }, req.body, { new: true })
    .exec()
    .then((customer) => {
      res.json(customer);
    })
    .catch((err) => {
      res.json({
        error: err,
      });
    });
});

findByIdAndUpdate() is used to update the customer. This method takes the following three argument:

  • id:. This is the id of the customer in the database and is passed as a route parameter.
  • Data: This is passed as a payload through the body of the PATCH request.
  • { new: true }: This ensures that when we update the customer, the response sent shows the updated information of the customer.

If we want to update the phone number of the customer “John Doe”, we make a PATCH request to “http://localhost:9001/602773db484c00004b966255” and pass the body as "phone": 636389037 which is the new phone number. And to see the updated information as a response of the successful request, we add { new: true } as the third parameter.

Deleting a customer

We will create an DELETE endpoint to delete a customer from the database.

//Delete customer by ID
app.delete("/:id", (req, res, next) => {
  const id = req.params.id;
  Customer.findByIdAndRemove({ _id: id })
    .exec()
    .then((customer) => {
      res.json(customer);
    })
    .catch((error) => {
      res.json({ error });
    });
});

findByIdAndRemove() is used to delete a customer from the database. Similar to the PATCH request, Delete request takes the id of the customer which is passed as a route parameter attached to the endpoint. For example, If we want to delete the customer “John Doe” from the database, we make a DELETE request to “http://localhost:9001/602773db484c00004b966255”