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.
- Project Setup Install Dependencies:
npm init -y
npm install express mongoose dotenv cors helmet morgan jsonwebtoken bcryptjs
npm install --save-dev nodemon
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
- Setting Up CRUD Operations Step 1: Configure Environment and Server .env
PORT=5000
MONGO_URI=mongodb://localhost:27017/crud_db
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));
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;
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);
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
};
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);
}
};
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;
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'
});
};
step: 7
Make sure MongoDB is running and then start the server:
npx nodemon server.js
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"
}
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"
}
Delete a User (DELETE)
URL: http://localhost:5000/api/users/{id}
Top comments (0)