DEV Community

SOVANNARO
SOVANNARO

Posted on

Express + MongoDB + Swagger CRUD Sample

In this blog, we'll walk through creating a simple CRUD (Create, Read, Update, Delete) application using Express.js, MongoDB, and Swagger for API documentation. This guide will help you understand the basics of setting up a RESTful API with these technologies.

Prerequisites

Before we start, make sure you have the following installed:

  • Node.js and npm (Node Package Manager)
  • MongoDB (You can use a local instance or a cloud service like MongoDB Atlas)

Project Setup

  1. Initialize the Project: Create a new directory for your project and initialize it with npm.
   mkdir express-sample-crud
   cd express-sample-crud
   npm init -y
Enter fullscreen mode Exit fullscreen mode
  1. Install Dependencies: Install the necessary packages for your project.
   npm install express mongoose body-parser cors dotenv swagger-jsdoc swagger-ui-express
Enter fullscreen mode Exit fullscreen mode

Project Structure

Here's a brief overview of the project structure:

express-sample-crud/
│
├── config/
│   ├── db.js
│   └── swagger.js
│
├── controllers/
│   └── userController.js
│
├── models/
│   └── userModel.js
│
├── routes/
│   └── userRoutes.js
│
├── my-express-app/
│   ├── .env
│   └── app.js
│
└── package.json
Enter fullscreen mode Exit fullscreen mode

Step-by-Step Guide

1. Database Configuration

Create a db.js file in the config directory to set up the MongoDB connection.

const mongoose = require("mongoose");
const dotenv = require("dotenv");

dotenv.config();

const connectDB = async () => {
  try {
    await mongoose.connect(process.env.MONGO_URI, {
      useNewUrlParser: true,
      useUnifiedTopology: true,
    });
    console.log("MongoDB connected");
  } catch (err) {
    console.error(err.message);
    process.exit(1);
  }
};

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

2. Swagger Configuration

Create a swagger.js file in the config directory to set up Swagger for API documentation.

const swaggerJsdoc = require("swagger-jsdoc");
const swaggerUi = require("swagger-ui-express");

const options = {
  definition: {
    openapi: "3.0.0",
    info: {
      title: "My Express API",
      version: "1.0.0",
      description: "A simple Express API with CRUD operations",
    },
    servers: [
      {
        url: "http://localhost:5000",
      },
    ],
  },
  apis: ["./routes/*.js"],
};

const specs = swaggerJsdoc(options);

module.exports = (app) => {
  app.use("/api-docs", swaggerUi.serve, swaggerUi.setup(specs));
};
Enter fullscreen mode Exit fullscreen mode

3. User Model

Create a userModel.js file in the models directory to 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,
  },
  password: {
    type: String,
    required: true,
  },
});

module.exports = mongoose.model("User", UserSchema);
Enter fullscreen mode Exit fullscreen mode

4. User Controller

Create a userController.js file in the controllers directory to handle the CRUD operations.

const User = require("../models/userModel");

exports.getUsers = async (req, res) => {
  try {
    const users = await User.find();
    res.json(users);
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
};

exports.createUser = async (req, res) => {
  const { name, email, password } = req.body;
  try {
    const newUser = new User({ name, email, password });
    await newUser.save();
    res.status(201).json(newUser);
  } catch (err) {
    res.status(400).json({ message: err.message });
  }
};

exports.updateUser = async (req, res) => {
  const { id } = req.params;
  const { name, email, password } = req.body;
  try {
    const user = await User.findByIdAndUpdate(
      id,
      { name, email, password },
      { new: true }
    );
    if (!user) {
      return res.status(404).json({ message: "User not found" });
    }
    res.json(user);
  } catch (err) {
    res.status(400).json({ message: err.message });
  }
};

exports.deleteUser = async (req, res) => {
  const { id } = req.params;
  try {
    const user = await User.findByIdAndDelete(id);
    if (!user) {
      return res.status(404).json({ message: "User not found" });
    }
    res.json({ message: "User deleted successfully" });
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
};
Enter fullscreen mode Exit fullscreen mode

5. User Routes

Create a userRoutes.js file in the routes directory to define the API endpoints.

const express = require("express");
const {
  getUsers,
  createUser,
  updateUser,
  deleteUser,
} = require("../controllers/userController");
const router = express.Router();

/**
 * @swagger
 * components:
 *   schemas:
 *     User:
 *       type: object
 *       required:
 *         - name
 *         - email
 *         - password
 *       properties:
 *         name:
 *           type: string
 *           description: The user's name
 *         email:
 *           type: string
 *           description: The user's email
 *         password:
 *           type: string
 *           description: The user's password
 *       example:
 *         name: John Doe
 *         email: john.doe@example.com
 *         password: password123
 */

/**
 * @swagger
 * /api/users:
 *   get:
 *     summary: Get all users
 *     responses:
 *       200:
 *         description: A list of users
 *         content:
 *           application/json:
 *             schema:
 *               type: array
 *               items:
 *                 $ref: '#/components/schemas/User'
 */
router.get("/users", getUsers);

/**
 * @swagger
 * /api/users:
 *   post:
 *     summary: Create a new user
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             $ref: '#/components/schemas/User'
 *     responses:
 *       201:
 *         description: The created user
 *         content:
 *           application/json:
 *             schema:
 *               $ref: '#/components/schemas/User'
 *       400:
 *         description: Invalid input
 */
router.post("/users", createUser);

/**
 * @swagger
 * /api/users/{id}:
 *   put:
 *     summary: Update a user
 *     parameters:
 *       - in: path
 *         name: id
 *         schema:
 *           type: string
 *         required: true
 *         description: The user ID
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             $ref: '#/components/schemas/User'
 *     responses:
 *       200:
 *         description: The updated user
 *         content:
 *           application/json:
 *             schema:
 *               $ref: '#/components/schemas/User'
 *       404:
 *         description: User not found
 */
router.put("/users/:id", updateUser);

/**
 * @swagger
 * /api/users/{id}:
 *   delete:
 *     summary: Delete a user
 *     parameters:
 *       - in: path
 *         name: id
 *         schema:
 *           type: string
 *         required: true
 *         description: The user ID
 *     responses:
 *       200:
 *         description: User deleted successfully
 *       404:
 *         description: User not found
 */
router.delete("/users/:id", deleteUser);

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

6. Environment Variables

Create a .env file in the my-express-app directory to store environment variables.

MONGO_URI=mongodb://localhost:27017/express_crud
PORT=5000
Enter fullscreen mode Exit fullscreen mode

7. Main Application File

Create an app.js file in the my-express-app directory to set up the Express application.

const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const dotenv = require("dotenv");
const connectDB = require("./config/db");
const userRoutes = require("./routes/userRoutes");
const swaggerSetup = require("./config/swagger");

dotenv.config();

const app = express();

// Connect to MongoDB
connectDB();

// Middleware
app.use(bodyParser.json());
app.use(cors());

// Routes
app.use("/api", userRoutes);

// Swagger setup
swaggerSetup(app);

const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
Enter fullscreen mode Exit fullscreen mode

8. Package Configuration

Update your package.json file to include the necessary scripts and dependencies.

{
  "name": "express-sample-crud",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": "",
  "dependencies": {
    "body-parser": "^1.20.3",
    "cors": "^2.8.5",
    "dotenv": "^16.4.7",
    "express": "^4.21.2",
    "mongoose": "^8.11.0",
    "swagger-jsdoc": "^6.2.8",
    "swagger-ui-express": "^5.0.1"
  }
}
Enter fullscreen mode Exit fullscreen mode

Running the Application

  1. Start your MongoDB server.
  2. Run the application using the following command:
   node app.js
Enter fullscreen mode Exit fullscreen mode
  1. Open your browser and navigate to http://localhost:5000/api-docs to view the Swagger API documentation.

Conclusion

You've successfully created a CRUD application using Express.js, MongoDB, and Swagger. This setup provides a solid foundation for building more complex applications.

Don't forget to follow me on GitHub for more projects and updates: My GitHub Profile

You can find the source code for this project on GitHub: Express + MongoDB + Swagger CRUD Sample

Top comments (0)