DEV Community

Cover image for From Zero to CRUD Hero: Building Your First Backend API in JavaScript
Zechariah Hounwanou
Zechariah Hounwanou

Posted on

From Zero to CRUD Hero: Building Your First Backend API in JavaScript

Application Programming Interface embed also known as API is the fundamental concept for interacting with data stored in a database. The process of setting it up can be time-consuming and difficult without adequate guidance. As a developer, you must understand how to efficiently develop CRUD (Create, Read, Update, and Delete) API for web applications.

For a developer to build a robust and flexible API for applications, the ability to set up routes, handle HTTP requests, send back HTTP responses, connect to the MongoDB database, and implement CRUD operations by leveraging on the capabilities of Node.js, Express.js, and MongoDB is needed.

This tutorial will walk you through the step-by-step process of building a RESTful CRUD API, from setting up the project development environment to connecting with the MongoDB database, then defining a data model with Mongoose which will interact with the MongoDB database cluster, then implementing the CRUD functionalities using Express routes and finally testing the API endpoints. You will also learn how to handle validations and errors. Upon completing this tutorial, you will be able to build dynamic CRUD APIs with efficient and safe data management capabilities.

What is Node.js

Node.js is a cross-platform runtime environment that runs JavaScript code on the server rather than in the browser. Node.js helps to create scalable and high-performance applications.

What is Express.js

Express.js is a Node.js framework that provides a robust set of features for developing Web APIs. It integrates with Node.js, making the creation of APIs simpler.

Architecture

The API will be built using a three-layer architecture based on Node.js, Express.js, and MongoDB.

CRUD API Architecture

The Data Access Layer is where we'll communicate and interact with our database.

Inside the Controller layer, we will handle the entire business logic that is associated with our endpoint's HTTP requests and responses.

The Router layer will send URLs to the appropriate controller functions. The router functionality will be obtained from Express.
Our API architecture for building CRUD APIs is straightforward, simple, and easy to understand.

What is CRUD API?

Since the beginning of this article, we have been hearing the term CRUD API. Let's take a closer look at it now.

A CRUD API refers to the basic operations that can be performed on the data in a database to enable it to interact with the application. They are used as building blocks in web development to create applications that require data persistence and manipulation.

So, the phrase CRUD refers to the ability to CREATE, READ, UPDATE, and DELETE entities from a database.

Understanding Each Functionality/Operation

CREATE: This functionality allows the creation of new data in the database.

READ: This functionality allows the retrieval of existing data from the database.

UPDATE: This functionality enables modification of existing data that is already in the database.

DELETE: This functionality allows the removal of existing data that is no longer wanted from the database.

Prerequisite

You do not need to be an expert to follow along with this tutorial, but you will need the following:

  1. Solid understanding of JavaScript
  2. Knowledge of Node.js and Express.js.
  3. Download and install Node and Postman on your machine.
  4. Download and install the VSCode text editor on your computer.

Setting Up Application Development Environment

This tutorial will use VSCode, but any text editor should work. To begin, let's create our development environment. We will not complicate the setup but rather create a simple and orderly project structure for our RESTful CRUD API. To make things easier, we'll split the following sections into two:

  1. Setting up the project and installing dependencies.
  2. Creating the Basic Express Server.

Setting up the project and installing dependencies

By typing the following command in our command prompt or command line interface, we can construct the overall project structure, including all relevant folders and files.

Navigating to the Desktop

cd Desktop

Create a project folder and navigate into it

mkdir book-management-api && cd book-management-api

Create a src folder and navigate into it

mkdir src && cd src

Create subfolders in the src folder

mkdir model && mkdir controllers && mkdir routes && mkdir db

We need to move one level up since we are in the src folder

cd ..

Create an entry point for our API in the root directory

touch index.js

Initialing our node app and creating a package.json file

npm init –y

When you run the above commands, your package.json file and application project structure should be produced. Now launch your project in VSCode using the command below.
code .

1. Installing Node.js newly

Now that you've successfully set up your development environment, your package.json file should look like the above. Next, we'll add additional development dependencies to our project. To install, open a terminal and enter the following command.

npm install express dotenv mongoose
Enter fullscreen mode Exit fullscreen mode
  • Express: a flexible Node.js web app framework

  • Dotenv: it loads environment variables from a .env file

  • Mongoose: it is a MongoDB object modeling tool designed to work in an asynchronous environment.

After installing the essential dependencies, your updated package.json file should look like this:

2. Successfully Installed dependencies

Creating the Basic Express Server

Now let's configure our web server. In the entry file index.js, add the following code:

require("dotenv").config();
const express = require("express");

const app = express();

app.get("/", (req, res) => {
  res.send("Hey! Sever is Up.");
});

const PORT = process.env.PORT || 5000;

app.listen(PORT, () => {
  console.log(`Server Listening on Port ${PORT}`);
});
Enter fullscreen mode Exit fullscreen mode

The code above accomplishes the following;
(i). We imported dotenv and used the .config() function to initialize it instantly.
(ii). We imported Express and assigned it to a variable named app. This variable now has access to all express methods.
(iii). Then we create a simple route (/) that sends "Hey! Server is up." We received a response when we accessed it.
(iv). Finally, we listen for all incoming requests on port 5000, which we have set as our server origin.

Let’s start the server, go back to your terminal, and run this command:

To Start the server

node index.js
Once everything is completed, open your browser and navigate to http://localhost:5000; you should see "Hey! Server is up" displayed on the screen.

We have one drawback with the node index.js command we used before, it restarts our server every time the file is altered. To make it easier to execute our Node program, we'll add a new start script to our package.json file. Use the command below to install it:

npm install -D nodemon
Enter fullscreen mode Exit fullscreen mode

Once installed, insert the following script into the package.json file:

 "scripts": {
    "start": "nodemon index.js"
  },
Enter fullscreen mode Exit fullscreen mode

The package.json file should look like this:

3. added Nodemon and its script

Use the following command to run the server and verify that everything is working correctly:

npm run start
Enter fullscreen mode Exit fullscreen mode

NOTE: Always move to the root directory before running the server.

The message in the terminal will indicate whether or not the above command has launched the Express server.

4. server starting

From what we can see above our express server is running. You will also see the image below if you go to the URL http://localhost:5000 in your browser

5. using Nodemon to run server

Voila! The project is perfectly set up. In the next section, we will set up our MongoDB Atlas account, Database Cluster, and then retrieve our connection string from MongoDB.

How to Connect a Node.js application to a MongoDB Database Cluster.

In this part of the tutorial, we'll connect our MongoDB database cluster to our Node application using the connection string and also configure our Node application to connect to our database. To make learning easier, we have divided this section into 3 parts:

  1. Setting up MongoDB Atlas, setting up the database cluster, and retrieving the connection strings.
  2. Configuring and Connecting the Node application to the Database.
  3. Modifying the Entry File to connect to our Express Server.

Setting up MongoDB Atlas, setting up database cluster, and retrieving the connection strings.

We will set up our MongoDB database, and then retrieve our connection string.

First, visit MongoDB Atlas and create an account, or sign in if you already have one. This article will guide you through the process of creating a MongoDB account. You should be redirected to your dashboard once you have completed the process. Locate the Connect button and click it.

7. mongoDB dashboard

The Drivers option will appear in the modal, select it so we can connect to our application immediately.

8. drivers options

Another modal will appear. Follow the steps below to set up your MongoDB driver and get your connection string:

  1. Select the latest Node.js driver and version.

  2. Install the driver package with NPM and install MongoDB.

  3. Copy and save it somewhere. The connection string will be used to connect the node application to MongoDB.

9. connection string section

We've successfully set up our MongoDB Atlas account, configured our MongoDB Cluster, and obtained the connection string.

Configuring and Connecting the Node application to the Database.

Create a .env file in the root directory. It will be used to securely store all of our application's sensitive information. Assign a value name to the connection string inside the .env file.

MONGO_URL=mongodb+srv://<databaseUsername>:<databasePassword>@nodeexp.4glzj53.mongodb.net/BOOK-LISTING-API?retryWrites=true&w=majority
Enter fullscreen mode Exit fullscreen mode

Note: Replace the above-mentioned database username and password with your own.

Within the db folder we created earlier, create a new file named connect.js. You can accomplish this by opening up the terminal and entering the following command:

Move to the src folder and then move to the db folder as well

cd src && cd db

Create a connect.js file

touch connect.js

Navigate from the db folder and then move back to the root folder

cd .. && cd ..
Now, our Node application's folder structure should look like the image below, with the newly created file included.

10. successfully created the connect.js file

Next, we need to define a method within the connect.js file that facilitates the connection between our Node.js application and the database. Include the following code in the connect.js file.

const mongoose = require("mongoose");

const connectDB = (url) => {
  return mongoose.connect(url);
};

module.exports = connectDB;
Enter fullscreen mode Exit fullscreen mode

In the code above, we imported Mongoose and constructed a connected function that returns a Promise that can be resolved or rejected via the URL, using the Mongoose connect() method. URL represents the connection string that should be added to the .env file.

Modifying the Entry File to connect our Express Server

In index.js, import the connectDB function at the top and construct a function that connects to our database and launches the server, which will listen for incoming requests once the connection is established.

const connectDB = require("./src/db/connect");

const start = async () => {
  try {
    await connectDB(process.env.MONGO_URL);
    app.listen(PORT, () => {
      console.log("Database & Node app connected Successfully");
    });
  } catch (error) {
    console.log(error);
  }
};

start();
Enter fullscreen mode Exit fullscreen mode

Because our connectDB function returns a Promise, the preceding code uses async/await in its start function. The Express server will automatically begin listening for incoming requests once the asynchronous function is resolved and the database connection is established.

11. server connected node to mongoDB

After restarting the Node application, you should see the above message, which indicates that your database and application have been synchronized. Good on so far, Let's keep going.

Creating a RESTful CRUD API.

Node JS uses the MVC (Model View Controller) architecture. It's a design pattern. Based on the idea, we will create the following API endpoints for our Book Management:

  1. POST /book - Create or add a new book.

  2. GET /book - Retrieve all books available.

  3. Get /book/:id - Retrieve a specific book.

  4. PATCH /book/:id - Update a book.

  5. Delete /book/:id - DELETE a book.

In the first step, we will create the model, followed by the CRUD API operations which will store and retrieve all data in MongoDB.

Creating a Model

A model is a fancy constructor derived from a schema. They create and read documents from the underlying MongoDB database. In other words, they form part of the development that represents and handles data. Models are the blueprints that organize our application's data. They describe what can be created, read, updated, and deleted as well as the structure, behavior, and actions that are allowed. We can define our data structure with Mongoose's schema.

Create a Book.js file within the model folder. To accomplish this, run the following commands:

Move to the src folder and then move to the db folder as well

cd src && cd model

Create a book.js file (To Define Model structure)

touch Book.js

Navigate from the db folder and then move back to the root folder

cd .. && cd ..

After executing the command to create the Book.js model file, our Node application's folder structure should look like the image below, with the newly created file included.

12. Newly added Book.js file

Next, we'll create a simple book schema with its fields included. In the newly created Book.js file, include the following code:

const mongoose = require("mongoose");

const bookSchema = new mongoose.Schema({
  title: String,
  author: String,
  publicationYear: Number,
  isStared: Boolean,
});

const Book = mongoose.model("Book", bookSchema);

module.exports = Book;
Enter fullscreen mode Exit fullscreen mode

With the code above we accomplish the following.
(i). Imported the Mongoose library to communicate with MongoDB in our Node.js project.
(ii). Used mongoose.Schema() to create the database schema structure for our book document in the MongoDB database.
(iii). Title, Author, PublicationYear, and isStared indicate the specific fields in each book document.
(iv). The mongoose.model() function creates a model based on the database schema structure we supplied. In addition, we exported the Book model so that it could be reused in other files.

Building a CRUD API that uses MongoDB

Now that we have structured the schema of our API, let's start by talking about the two most critical components of a RESTful CRUD API: controllers and routes.

Controllers are responsible for processing data, making decisions, and orchestrating API flows. They receive requests from routes, interact with the model, and determine the response to give to the client. They include business logic for handling individual requests and generating responses.

Route functions are similar to maps, directing incoming requests to the proper location inside the application. They define which URLs clients can access and what happens when they are visited. Routes are paths users can follow to explore your application, and each route corresponds to a specific function or collection of functions that process requests and respond to them.

How Controllers and Routes Work Together in Node.js Applications

Routes serve as the entry point for receiving requests in a Node.js application. When the router receives the request, it determines which route should handle it depending on the URL and HTTP method.

Next, after identifying the right route, the router calls the controller function associated with it. A controller executes business logic by retrieving data from the request and using it to perform actions such as validating input, generating a response, and retrieving data from the database.

After processing the request, handling the business logic, and generating a response, the controller returns it to the router, which sends it back to the client.

Creating a Controller

Create a file called bookControllers.js in the src/controllers folder. To accomplish this, run the following commands:

Move to the src folder and then move to the db folder as well

cd src && cd controllers

Create a bookController.js file in the controllers folder

touch bookControllers.js

Navigate from the db folder and then move back to the root folder

cd .. && cd ..

After executing the command to create the bookControllers.js file, our Node application's folder structure should look like the image below, with the newly created file included.

13. newly added book controller file

Next, we need to add the following functions to bookController.js, which will function as a communication interface with the Book model, as well as a method to handle CRUD API business logic, as well as a method to forward responses to other parts of the application.

const Book = require('../model/Book');

const createBook = (req, res) => {};
const getAllBooks = (req, res) => {};
const getSingleBook = (req, res) => {};
const updateSingleBook = (req, res) => {};
const deleteBook = (req, res) => {};

module.exports = {
  createBook,
  getAllBooks,
  getSingleBook,
  updateSingleBook,
  deleteBook,
};
Enter fullscreen mode Exit fullscreen mode

Let's examine each controller function in the bookController.js file one by one to see how it implements the business logic.

Logic 1: Create a book

Inside the entry file index.js, add the following built-in Express middleware function:

app.use(express.json());
Enter fullscreen mode Exit fullscreen mode

The code above creates middleware that parses incoming JSON data from the request body and makes it available for your express application in req.body.

Note: This is required for managing JSON data in the application, such as processing data submitted via forms or API requests.

Next, open the bookController.js file. Using the Book model, we can create a document for every book in our database cluster.

const createBook = async (req, res) => {
  const book = await Book.create(req.body);
  res.status(201).json({book})
};
Enter fullscreen mode Exit fullscreen mode

Logic 2: Retrieve all books.

Next, inside the bookController.js file. To access the complete list of books available in our API, use the .find({}) function on the Book model.

const getAllBooks = async (req, res) => {
  const books = await Book.find({});
 res.status(200).json({books})
};
Enter fullscreen mode Exit fullscreen mode

Logic 3: Retrieve a Single Book

Our next step will be to retrieve a single book from the database using its unique ID.

const getSingleBook = async (req, res) => {
  const { id: bookId } = req.params;
  const singleBook = await Book.findOne({ _id: bookId });
  res.status(200).json({ singleBook });
};
Enter fullscreen mode Exit fullscreen mode

The code above accomplishes the following:

(i). Assign the ID parameter from the request parameter object req.params to a variable called bookId. When you make a request, the URL will include the ID.
(ii). The Book.findOne() method searches the database for a single document with the _id field matching the bookIdfrom the request parameters.

Logic 4: Update a book

Next, we'll update a book document in the database.

const updateSingleBook = async (req, res) => {
  const { id: bookId } = req.params;
  const singleBook = await Book.findOneAndUpdate({ _id: bookId }, req.body, {
    new: true,
    runValidators: true,
  });
  res.status(200).json({ singleBook });
};
Enter fullscreen mode Exit fullscreen mode

In the code above, the following is done:
(i). The const {id: bookId} = req.params method extracts the id parameter from the request and applies it to the bookId variable.
(ii). The findOneAndUpdate() method changes a single book document stored in the database.
(iii). It searches for a book document using the bookId and changes it with data from the request body.
(iv). While the new:true option returns the revised document, the runValidators:true option executes Mongoose validators.

Logic 5: Delete a book

Finally, removing a single book from the database depends on its ID. Add the code below to the bookController.js file.

const deleteBook = async (req, res) => {
  const { id: bookId } = req.params;
  const deleteBook = await Book.findOneAndDelete({ _id: bookId });
  res.status(200).json({ deleteBook });
};
Enter fullscreen mode Exit fullscreen mode

The above code performs the following:

(i). Assign the id parameter from the request parameter object req.params to a variable called bookId.
(ii). The Book model's findOneAndDelete() method deletes a single book document with a matching _idfield from the database.

We have developed all the business logic for the CRUD API operations we will be using. To generate the operations, we used the async and await keywords since the database query takes time, which is when the Node.js asynchronous attribute comes into play. The JSON response we return with each operation includes the status code as well as the book document stored in our database.

Defining Routes

When a client sends a request for an endpoint via HTTP requests (GET, POST, PATCH, DELETE), we need to define how the server will respond by setting up the routes.

Create a file called bookRoute.js in the src/routes folder. To do this task, open your terminal and type the following commands:

Move to the src folder and then move to the db folder as well

cd src && cd routes

Create a bookRoutes.js file in the controllers folder

touch bookRoutes.js

Navigate from the db folder and then move back to the root folder

cd .. && cd ..

After executing the command to create the bookRoutes.js file, our Node application's folder structure should look like the image below, with the newly created file included.

14. newly added book routes file

Next, we'll set up routes for each controller. Include the following code content:

const express = require("express");
const {
  createBook,
  getAllBooks,
  getSingleBook,
  updateSingleBook,
  deleteBook,
} = require("../controllers/bookControllers");
const router = express.Router();

router.post("/", createBook);
router.get("/", getAllBooks);
router.get("/:id", getSingleBook);
router.patch("/:id", updateSingleBook);
router.delete("/:id", deleteBook);

module.exports = router;
Enter fullscreen mode Exit fullscreen mode

In the code snippet,
(i). Our API is built using the Express package, which provides the functionality that we need.
(ii). Express Router is middleware that organizes application routes. The const router = express.Router() method is used to create a new router object using Express Router.
(iii). const {...} = require("../controllers/bookControllers")imports all business logic functions from bookControllers.js.
(iv). There are four types of routes: router.post, router.get, router.patch, and router.delete, linked by URL patterns and controllers.
(v). We export the router object for use in index.js.

Finally, we must register the bookRoute.js file in our entry file index.js so that any calls to endpoints are redirected to the correct URL path. To accomplish this, we'll add the following code to the index.js file:

const bookRouter = require("./src/routes/bookRoutes");
Enter fullscreen mode Exit fullscreen mode

Use the app.use() function, specifying the path and router handler.

app.use("/api/v1/books", bookRouter);
Enter fullscreen mode Exit fullscreen mode

When we access the URL http://localhost:5000/api/v1/books, the router is activated. It effectively functions as a filter, determining when a particular set of routes should be used.

Here's the whole complete code for the index.js file:

require("dotenv").config();
const express = require("express");
const connectDB = require("./src/db/connect");
const bookRouter = require("./src/routes/bookRoutes");

const app = express();

app.use(express.json());

app.get("/", (req, res) => {
  res.send("Hey! Sever is Up.");
});

app.use("/api/v1/books", bookRouter);

const PORT = process.env.PORT || 3000;

const start = async () => {
  try {
    await connectDB(process.env.MONGO_URL);
    app.listen(PORT, () => {
      console.log("Database & Node app connected Successfully");
    });
  } catch (error) {
    console.log(error);
  }
};
start();
Enter fullscreen mode Exit fullscreen mode

Congratulations! We have successfully integrated the MongoDB database into our Node.js application and built the CRUD API action. Before we test our API, let's add some basic validation and error handling to improve its reliability and usability.

Basic Validation and Error Handling

Let's work on improving our CRUD API now that it has connected to our MongoDB cluster and we have set up CRUD API operations.

For any API, error handling and data validation are crucial to ensuring the API responds appropriately to incorrect inputs and unexpected scenarios, thus improving the user experience.

If a user tries to add a book without a title, author, or publication year, they will be unable to do so. Without effective validation, our database may contain incomplete data. When error validation and error handling are in place, users will be informed of what went wrong rather than left in the dark.

Adding basic validation

As a first step, let's validate our Book model. Add basic validation to Book.js in the model folder.

const mongoose = require("mongoose");

const bookSchema = new mongoose.Schema({
  title: { type: String, required: [true, "Please Provide a Title"] },
  author: { type: String, required: [true, "Please Provide Author Name"] },
  publicationYear: {
    type: Number,
    required: [true, "Please Provide Publication Year"],
  },
  isStared: { type: Boolean, default: false },
});

const Book = mongoose.model("Book", bookSchema);

module.exports = Book;
Enter fullscreen mode Exit fullscreen mode

Mongoose will produce an error if we create a book without a title, author, or publication year because those fields are required, and the error message will explain what went wrong.

Implementing error handling

An effective error management process involves detecting errors and responding appropriately to them. To handle errors graciously, let's improve our bookController.js CRUD API action.

Create a Book with Error Handling

const createBook = async (req, res) => {
  try {
    const book = await Book.create(req.body);
    res.status(201).json({ book });
  } catch (error) {
    res.status(400).json({ msg: error });
  }
};
Enter fullscreen mode Exit fullscreen mode

Retrieving All Books with Error Handling

const getAllBooks = async (req, res) => {
  try {
    const books = await Book.find({});
    res.status(200).json({ books });
  } catch (error) {
    res.status(400).json({ msg: error });
  }
};
Enter fullscreen mode Exit fullscreen mode

Get a Single Book with Error Handling

const getSingleBook = async (req, res) => {
  try {
    const { id: bookId } = req.params;
    const singleBook = await Book.findOne({ _id: bookId });
    if (!singleBook) {
          return res.status(404).json({ msg: `No Book with Id ${bookId}` });
    }
    res.status(200).json({ singleBook });
  } catch (error) {
    res.status(400).json({ msg: error });
  }
};
Enter fullscreen mode Exit fullscreen mode

Update the Book with Error Handling

const updateSingleBook = async (req, res) => {
  try {
    const { id: bookId } = req.params;
    const singleBook = await Book.findOneAndUpdate({ _id: bookId }, req.body, {
      new: true,
      runValidators: true,
    });
    if (!singleBook) {
          return res.status(404).json({ msg: `No Book with Id ${bookId}` });

    }
    res.status(200).json({ singleBook });
  } catch (error) {
    res.status(400).json({ msg: error });
  }
};
Enter fullscreen mode Exit fullscreen mode

Delete a Book with Error Handling

const deleteBook = async (req, res) => {
  try {
    const { id: bookId } = req.params;
    const deleteBook = await Book.findOneAndDelete({ _id: bookId });
    if (!deleteBook) {
      return res.status(404).json({ msg: `No Book with Id ${bookId}` });
    }
    res.status(200).json({ deleteBook });
  } catch (error) {
    res.status(400).json({ msg: error });
  }
};
Enter fullscreen mode Exit fullscreen mode

We implemented try-catch blocks in all of our CRUD API operations to ensure that every issue detected is handled appropriately. With these additions, our CRUD API now includes comprehensive error handling and validation capabilities. This not only makes our API more stable but also enhances the user experience by displaying clear and informative error messages.

Here is the complete code for the bookController.js file:

const Book = require("../model/Book");

const createBook = async (req, res) => {
  try {
    const book = await Book.create(req.body);
    res.status(201).json({ book });
  } catch (error) {
    res.status(400).json({ msg: error });
  }
};

const getAllBooks = async (req, res) => {
  try {
    const books = await Book.find({});
    res.status(200).json({ books });
  } catch (error) {
    res.status(400).json({ msg: error });
  }
};

const getSingleBook = async (req, res) => {
  try {
    const { id: bookId } = req.params;
    const singleBook = await Book.findOne({ _id: bookId });
    if (!singleBook) {
      return res.status(404).json({ msg: `No Book with Id ${bookId}` });
    }
    res.status(200).json({ singleBook });
  } catch (error) {
    res.status(400).json({ msg: error });
  }
};

const updateSingleBook = async (req, res) => {
  try {
    const { id: bookId } = req.params;
    const singleBook = await Book.findOneAndUpdate({ _id: bookId }, req.body, {
      new: true,
      runValidators: true,
    });
    if (!singleBook) {
      return res.status(404).json({ msg: `No Book with Id ${bookId}` });
    }
    res.status(200).json({ singleBook });
  } catch (error) {
    res.status(400).json({ msg: error });
  }
};

const deleteBook = async (req, res) => {
  try {
    const { id: bookId } = req.params;
    const deleteBook = await Book.findOneAndDelete({ _id: bookId });
    if (!deleteBook) {
      return res.status(404).json({ msg: `No Book with Id ${bookId}` });
    }
    res.status(200).json({ deleteBook });
  } catch (error) {
    res.status(400).json({ msg: error });
  }
};

module.exports = {
  createBook,
  getAllBooks,
  getSingleBook,
  updateSingleBook,
  deleteBook,
};
Enter fullscreen mode Exit fullscreen mode

In the next section of the tutorial, we will test our CRUD API to ensure its stability and robustness. We are close to the finish line.

Testing the CRUD API

After implementing error handling and validation, it is critical to test our CRUD API. Testing ensures that everything works as planned and detects any problems before they affect our users. Let's get started testing our CRUD API using Postman.

Test each endpoint

15. Testing Creating Book endpoint

16. Testing all book endpoint

  • To retrieve a single book, use the GET method and include the Book ID in the URL. If the Book ID is incorrect, it will return an error message; however, if the Book ID is correct, it will provide detailed information about that book.

17. Testing getting single book endpoint

  • The content of a book can be updated by submitting a PACTH request with the new data for the specified Book ID. You will get an error message if the Book ID is incorrect. The new data should, however, be inserted correctly into the book.

18. Testing updating book endpoint

  • To delete a book from the database, use the DELETE method on the book endpoint and enter the Book ID.

19. Testing delete book endpoint

Congratulations! We did it. After testing the CRUD API we created, they are now fully operational. The tutorial started with setting up our development environment and ended with building our API. That's an impressive achievement, and we should be proud of it.

Conclusion

That was a fantastic ride. I enjoyed creating this piece of content for you and learned a lot in the process. Building a basic CRUD API from scratch is a difficult task that demands patience, perseverance, and the willingness to learn. Fortunately for me, you have shown all of these qualities and more.

In this tutorial, we looked at backend development by creating a simple Book CRUD API with Node.js and Express.js. This tutorial covered a wide range of topics, including setting up our development environment, creating our MongoDB Atlas account and retrieving our connection string, developing CRUD APIs using Express.js and Node.js, and testing them using Postman.

Congratulations on creating your CRUD API with Node.js and Express! Here's to many more coding adventures ahead. May the codes be with you!

If you could provide feedback, I would greatly appreciate it. Please post it in the comments section. If you find this tutorial helpful, please consider sharing it with others who might find it helpful too.

Top comments (0)