You’ve learned Node.js. You’ve tamed Express. You’ve befriended MongoDB. Now it’s time to assemble the Avengers. In this chapter, you’ll build a fully functional CRUD backend — the kind used in real apps like social networks, dashboards, and e‑commerce platforms.
What We’re Building
A Product Management API with:
- Create product
- Get all products
- Get single product
- Update product
- Delete product
This mirrors real‑world backend architecture.
Project Structure (Clean & Professional)
backend-series/
│
├── app.js
├── db.js
├── models/
│ └── Product.js
├── controllers/
│ └── productController.js
├── routes/
│ └── productRoutes.js
└── package.json
This structure is how real companies organize backend code.
Step 1 — Product Model (MongoDB + Mongoose)
Create:
models/Product.js
const mongoose = require('mongoose');
const productSchema = new mongoose.Schema({
name: { type: String, required: true },
price: { type: Number, required: true },
description: String,
inStock: { type: Boolean, default: true },
createdAt: { type: Date, default: Date.now }
});
module.exports = mongoose.model('Product', productSchema);
This defines how product documents look in MongoDB.
Step 2 — Product Controller (Logic Lives Here)
Create:
controllers/productController.js
const Product = require('../models/Product');
// CREATE
exports.createProduct = async (req, res) => {
try {
const product = await Product.create(req.body);
res.json({ message: 'Product created', product });
} catch (error) {
res.status(400).json({ error: error.message });
}
};
// READ ALL
exports.getProducts = async (req, res) => {
const products = await Product.find();
res.json(products);
};
// READ ONE
exports.getProduct = async (req, res) => {
const product = await Product.findById(req.params.id);
res.json(product);
};
// UPDATE
exports.updateProduct = async (req, res) => {
const product = await Product.findByIdAndUpdate(req.params.id, req.body, { new: true });
res.json({ message: 'Product updated', product });
};
// DELETE
exports.deleteProduct = async (req, res) => {
await Product.findByIdAndDelete(req.params.id);
res.json({ message: 'Product deleted' });
};
Controllers keep your logic clean and reusable.
Step 3 — Product Routes (API Endpoints)
Create:
routes/productRoutes.js
const express = require('express');
const {
createProduct,
getProducts,
getProduct,
updateProduct,
deleteProduct
} = require('../controllers/productController');
const router = express.Router();
router.post('/', createProduct);
router.get('/', getProducts);
router.get('/:id', getProduct);
router.put('/:id', updateProduct);
router.delete('/:id', deleteProduct);
module.exports = router;
Routes = the doors to your API.
Step 4 — Connect Everything in app.js
app.js
const express = require('express');
const connectDB = require('./db');
const productRoutes = require('./routes/productRoutes');
const app = express();
app.use(express.json());
connectDB();
app.use('/api/products', productRoutes);
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});
Your API is now fully operational.
Step 5 — Testing Your API
Use Postman, Thunder Client, or cURL.
Create Product
POST → /api/products
Body:
{
"name": "Laptop",
"price": 2500,
"description": "A powerful machine"
}
Get All Products
GET → /api/products
Get One Product
GET → /api/products/:id
Update Product
PUT → /api/products/:id
Delete Product
DELETE → /api/products/:id
You now have a complete backend CRUD system.
What You’ve Achieved
You’ve built:
- A structured backend project
- A MongoDB database
- A Mongoose model
- Controllers for logic
- Routes for endpoints
- A fully functional CRUD API
This is the foundation of real production‑grade backend engineering.
Sources & Further Reading
- MongoDB Docs — https://www.mongodb.com/docs
- Express Docs — https://expressjs.com
- Mongoose Docs — https://mongoosejs.com/docs
- REST API Principles — https://restfulapi.net

