DEV Community

KISHAN RAMLAKHAN NISHAD
KISHAN RAMLAKHAN NISHAD

Posted on

A CRUD operation in the standard project structure for a Node.js backend application using Express.js and MongoDB.

Let's implement a CRUD operation in the standard project structure I provided above. We'll create a User model and perform basic Create, Read, Update, and Delete operations.

  1. Project Setup Install Dependencies:
npm init -y
npm install express mongoose dotenv cors helmet morgan jsonwebtoken bcryptjs
npm install --save-dev nodemon

Enter fullscreen mode Exit fullscreen mode

Folder Structure Recap:

/project-root
│
├── /src
│   ├── /config
│   ├── /controllers
│   ├── /middlewares
│   ├── /models
│   ├── /routes
│   ├── /services          # NEW: Business logic and database interaction
│   ├── /utils
│   └── app.js
│
├── .env
├── server.js
├── package.json
└── README.md

Enter fullscreen mode Exit fullscreen mode
  1. Setting Up CRUD Operations Step 1: Configure Environment and Server .env
PORT=5000
MONGO_URI=mongodb://localhost:27017/crud_db

Enter fullscreen mode Exit fullscreen mode

server.js

const app = require('./src/app');
const mongoose = require('mongoose');
require('dotenv').config();

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

mongoose.connect(process.env.MONGO_URI, {
    useNewUrlParser: true,
    useUnifiedTopology: true
}).then(() => {
    console.log('MongoDB Connected');
    app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
}).catch(err => console.error('MongoDB connection error:', err));

Enter fullscreen mode Exit fullscreen mode

Step 2: Setup Express App
/src/app.js

const express = require('express');
const cors = require('cors');
const morgan = require('morgan');
const helmet = require('helmet');
const userRoutes = require('./routes/userRoutes');
const { errorHandler } = require('./middlewares/errorMiddleware');

const app = express();

// Middlewares
app.use(helmet());
app.use(cors());
app.use(morgan('dev'));
app.use(express.json());

// Routes
app.use('/api/users', userRoutes);

// Error Handling Middleware
app.use(errorHandler);

module.exports = app;

Enter fullscreen mode Exit fullscreen mode

Step 3: Create the User Model
/src/models/userModel.js

const mongoose = require('mongoose');

const userSchema = new mongoose.Schema({
    name: {
        type: String,
        required: [true, 'Name is required']
    },
    email: {
        type: String,
        required: [true, 'Email is required'],
        unique: true
    },
    password: {
        type: String,
        required: [true, 'Password is required']
    }
}, { timestamps: true });

module.exports = mongoose.model('User', userSchema);

Enter fullscreen mode Exit fullscreen mode

step 4
Setting Up the Service Layer

Step a: Create the User Service
/src/services/userService.js

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

// Service to create a new user
const createUser = async (userData) => {
    const user = new User(userData);
    return await user.save();
};

// Service to get all users
const getAllUsers = async () => {
    return await User.find();
};

// Service to get user by ID
const getUserById = async (userId) => {
    return await User.findById(userId);
};

// Service to update user by ID
const updateUser = async (userId, updateData) => {
    return await User.findByIdAndUpdate(userId, updateData, { new: true, runValidators: true });
};

// Service to delete user by ID
const deleteUser = async (userId) => {
    return await User.findByIdAndDelete(userId);
};

module.exports = {
    createUser,
    getAllUsers,
    getUserById,
    updateUser,
    deleteUser
};

Enter fullscreen mode Exit fullscreen mode

setp 5. Update the Controller to Use the Service Layer
/src/controllers/userController.js

const userService = require('../services/userService');

// CREATE - Add new user
exports.createUser = async (req, res, next) => {
    try {
        const user = await userService.createUser(req.body);
        res.status(201).json({ success: true, data: user });
    } catch (err) {
        next(err);
    }
};

// READ - Get all users
exports.getUsers = async (req, res, next) => {
    try {
        const users = await userService.getAllUsers();
        res.status(200).json({ success: true, data: users });
    } catch (err) {
        next(err);
    }
};

// READ - Get user by ID
exports.getUserById = async (req, res, next) => {
    try {
        const user = await userService.getUserById(req.params.id);
        if (!user) {
            return res.status(404).json({ success: false, message: 'User not found' });
        }
        res.status(200).json({ success: true, data: user });
    } catch (err) {
        next(err);
    }
};

// UPDATE - Update user by ID
exports.updateUser = async (req, res, next) => {
    try {
        const user = await userService.updateUser(req.params.id, req.body);
        if (!user) {
            return res.status(404).json({ success: false, message: 'User not found' });
        }
        res.status(200).json({ success: true, data: user });
    } catch (err) {
        next(err);
    }
};

// DELETE - Remove user by ID
exports.deleteUser = async (req, res, next) => {
    try {
        const user = await userService.deleteUser(req.params.id);
        if (!user) {
            return res.status(404).json({ success: false, message: 'User not found' });
        }
        res.status(200).json({ success: true, message: 'User deleted successfully' });
    } catch (err) {
        next(err);
    }
};

Enter fullscreen mode Exit fullscreen mode

setp 6. Route Setup
The routes remain the same as before.

/src/routes/userRoutes.js

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

// Create a new user
router.post('/', createUser);

// Get all users
router.get('/', getUsers);

// Get a user by ID
router.get('/:id', getUserById);

// Update a user by ID
router.put('/:id', updateUser);

// Delete a user by ID
router.delete('/:id', deleteUser);

module.exports = router;

Enter fullscreen mode Exit fullscreen mode

Step 6: Error Handling Middleware

/src/middlewares/errorMiddleware.js

exports.errorHandler = (err, req, res, next) => {
    console.error(err.stack);
    res.status(500).json({
        success: false,
        message: err.message || 'Server Error'
    });
};

Enter fullscreen mode Exit fullscreen mode

step: 7

Make sure MongoDB is running and then start the server:

npx nodemon server.js

Enter fullscreen mode Exit fullscreen mode

step 8
Test the API Using Postman
Create a User (POST)
URL: http://localhost:5000/api/users
Body:

{
    "name": "Alice",
    "email": "alice@example.com",
    "password": "password123"
}

Enter fullscreen mode Exit fullscreen mode

Get All Users (GET)
URL: http://localhost:5000/api/users

Get a User by ID (GET)
URL: http://localhost:5000/api/users/{id}

Update a User (PUT)
URL: http://localhost:5000/api/users/{id}
Body:

{
    "name": "Alice Updated"
}

Enter fullscreen mode Exit fullscreen mode

Delete a User (DELETE)
URL: http://localhost:5000/api/users/{id}

Top comments (0)