Building a REST API with Node.js and MongoDB: A Step-by-Step Guide

November 2, 2024 (2w ago)

Building a REST API with Node.js and MongoDB: A Step-by-Step Guide

Building a REST API is essential for modern web applications, enabling you to interact with your backend using standard HTTP methods. In this guide, we’ll build a REST API with Node.js, Express, and MongoDB, covering everything from setting up the project to implementing CRUD operations. By the end, you’ll have a fully functional API that you can use as a backend for web or mobile applications.


Prerequisites

To follow along with this tutorial, you’ll need:

  1. Node.js and npm installed on your system.
  2. MongoDB installed locally or access to a MongoDB cloud instance (e.g., MongoDB Atlas).
  3. Basic understanding of JavaScript, Node.js, and REST APIs.

Project Setup

First, let’s set up a new Node.js project and install the necessary dependencies.

Step 1: Create a New Project

Open a terminal, create a new directory, and initialize a Node.js project:

mkdir rest-api
cd rest-api
npm init -y

Step 2: Install Dependencies

We’ll use Express for the web server and Mongoose for connecting to MongoDB.

npm install express mongoose dotenv

Configuring MongoDB Connection

We’ll store our MongoDB connection string in an .env file to keep it secure.

Step 1: Create a .env File

In the project root, create a .env file and add your MongoDB URI:

MONGODB_URI=mongodb://localhost:27017/rest_api
PORT=5000

Replace the MONGODB_URI value with your actual MongoDB connection string.

Step 2: Set Up the Database Connection

In the root directory, create a new file named server.js. This file will be the entry point for our application.

server.js

require("dotenv").config();
const express = require("express");
const mongoose = require("mongoose");
 
const app = express();
 
// Middleware
app.use(express.json());
 
// Connect to MongoDB
mongoose
  .connect(process.env.MONGODB_URI, { useNewUrlParser: true, useUnifiedTopology: true })
  .then(() => console.log("Connected to MongoDB"))
  .catch((error) => console.error("MongoDB connection error:", error));
 
// Start the server
const port = process.env.PORT || 3000;
app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});

In this setup:

Run the server to test the connection:

node server.js

If the connection is successful, you’ll see the message "Connected to MongoDB" in the terminal.


Defining the Data Model with Mongoose

Let’s create a simple data model for a User with fields for name, email, and age.

Step 1: Create a models Directory

Inside the project directory, create a models folder and a file named User.js.

Step 2: Define the User Model

In models/User.js, define the User schema:

const mongoose = require("mongoose");
 
const userSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
  },
  email: {
    type: String,
    required: true,
    unique: true,
  },
  age: {
    type: Number,
    required: true,
  },
});
 
module.exports = mongoose.model("User", userSchema);

This schema defines the structure of a user document with three fields: name, email, and age. Each field has a type and a validation rule.


Creating CRUD Routes for the API

Now, let’s create CRUD routes to manage users. We’ll define routes for creating, reading, updating, and deleting users.

Step 1: Create a routes Directory

Inside the project directory, create a routes folder and a file named users.js.

Step 2: Define User Routes

In routes/users.js, define routes for each CRUD operation:

const express = require("express");
const router = express.Router();
const User = require("../models/User");
 
// CREATE a new user
router.post("/", async (req, res) => {
  try {
    const user = new User(req.body);
    await user.save();
    res.status(201).json(user);
  } catch (error) {
    res.status(400).json({ message: error.message });
  }
});
 
// READ all users
router.get("/", async (req, res) => {
  try {
    const users = await User.find();
    res.json(users);
  } catch (error) {
    res.status(500).json({ message: error.message });
  }
});
 
// READ a single user by ID
router.get("/:id", async (req, res) => {
  try {
    const user = await User.findById(req.params.id);
    if (!user) return res.status(404).json({ message: "User not found" });
    res.json(user);
  } catch (error) {
    res.status(500).json({ message: error.message });
  }
});
 
// UPDATE a user by ID
router.put("/:id", async (req, res) => {
  try {
    const user = await User.findByIdAndUpdate(req.params.id, req.body, { new: true });
    if (!user) return res.status(404).json({ message: "User not found" });
    res.json(user);
  } catch (error) {
    res.status(400).json({ message: error.message });
  }
});
 
// DELETE a user by ID
router.delete("/:id", async (req, res) => {
  try {
    const user = await User.findByIdAndDelete(req.params.id);
    if (!user) return res.status(404).json({ message: "User not found" });
    res.json({ message: "User deleted" });
  } catch (error) {
    res.status(500).json({ message: error.message });
  }
});
 
module.exports = router;

Each route performs a CRUD operation:

Step 3: Connect Routes to the Server

In server.js, import the users route and add it to the app:

const userRoutes = require("./routes/users");
app.use("/users", userRoutes);

Your server.js file should now look like this:

require("dotenv").config();
const express = require("express");
const mongoose = require("mongoose");
 
const app = express();
app.use(express.json());
 
mongoose
  .connect(process.env.MONGODB_URI, { useNewUrlParser: true, useUnifiedTopology: true })
  .then(() => console.log("Connected to MongoDB"))
  .catch((error) => console.error("MongoDB connection error:", error));
 
const userRoutes = require("./routes/users");
app.use("/users", userRoutes);
 
const port = process.env.PORT || 3000;
app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});

Testing the API with Postman

You can use Postman or curl to test the API. Below are examples of API calls you can make:

  1. Create a User (POST): POST /users

    • Body: { "name": "Alice", "email": "alice@example.com", "age": 30 }
  2. Get All Users (GET): GET /users

  3. Get a Single User (GET): GET /users/:id

    • Replace :id with the actual user ID.
  4. Update a User (PUT): PUT /users/:id

    • Body: { "name": "Alice Updated" }
  5. Delete a User (DELETE): DELETE /users/:id

Each request will return a JSON response, and the status code will indicate whether the operation was successful or if an error occurred.


Conclusion

Congratulations! You’ve built a complete REST API using Node.js, Express, and MongoDB. This API supports CRUD operations for a User model and can be expanded to support additional models and endpoints. With this foundation, you can develop backends for web and mobile applications, implement authentication, add validation, or integrate with external services.

This project provides a solid introduction to building REST APIs and working with MongoDB, giving you a starting point for creating more complex and scalable applications.