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

SurveyJS custom survey software

Simplify data collection in your JS app with a fully integrated form management platform. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more. Integrates with any backend system, giving you full control over your data and no user limits.

Learn more

Top comments (0)

SurveyJS custom survey software

JavaScript Form Builder UI Component

Generate dynamic JSON-driven forms directly in your JavaScript app (Angular, React, Vue.js, jQuery) with a fully customizable drag-and-drop form builder. Easily integrate with any backend system and retain full ownership over your data, with no user or form submission limits.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay