CRUD Operations with Database
Now that you know how to connect to databases, it's time to build a complete **CRUD** application. CRUD stands for Create, Read, Update, Delete – the four basic operations for persistent storage. In this chapter, we'll build a complete REST API for a simple resource (like products or posts) using Express and a database.
What is CRUD?
| Operation | HTTP Method | Description |
|---|---|---|
| Create | POST | Add a new resource |
| Read | GET | Retrieve resources (single or list) |
| Update | PUT / PATCH | Modify an existing resource |
| Delete | DELETE | Remove a resource |
Think of CRUD as the foundation of any data-driven application. Almost everything you build will involve these four operations.
Project Setup
mkdir crud-apicd crud-apinpm init -ynpm install express mongoose dotenvnpm install --save-dev nodemonComplete CRUD Example with MongoDB/Mongoose
1. Model (models/Product.js)
const mongoose = require('mongoose');
const productSchema = new mongoose.Schema({ name: { type: String, required: true, trim: true }, price: { type: Number, required: true, min: 0 }, description: { type: String, maxlength: 500 }, category: { type: String, required: true }, inStock: { type: Boolean, default: true }, createdAt: { type: Date, default: Date.now }});
module.exports = mongoose.model('Product', productSchema);2. Database Connection (config/db.js)
const mongoose = require('mongoose');
const connectDB = async () => { try { await mongoose.connect(process.env.MONGODB_URI); console.log('MongoDB connected'); } catch (err) { console.error(err); process.exit(1); }};
module.exports = connectDB;3. Complete CRUD Routes (routes/products.js)
const express = require('express');const Product = require('../models/Product');const router = express.Router();
<!-- CREATE: POST /products -->router.post('/', async (req, res) => { try { const product = new Product(req.body); const savedProduct = await product.save(); res.status(201).json(savedProduct); } catch (err) { res.status(400).json({ error: err.message }); }});
<!-- READ ALL: GET /products -->router.get('/', async (req, res) => { try { const products = await Product.find().sort({ createdAt: -1 }); res.json(products); } catch (err) { res.status(500).json({ error: err.message }); }});
<!-- READ SINGLE: GET /products/:id -->router.get('/:id', async (req, res) => { try { const product = await Product.findById(req.params.id); if (!product) { return res.status(404).json({ error: 'Product not found' }); } res.json(product); } catch (err) { res.status(500).json({ error: err.message }); }});
<!-- UPDATE: PUT /products/:id -->router.put('/:id', async (req, res) => { try { const product = await Product.findByIdAndUpdate( req.params.id, req.body, { new: true, runValidators: true } ); if (!product) { return res.status(404).json({ error: 'Product not found' }); } res.json(product); } catch (err) { res.status(400).json({ error: err.message }); }});
<!-- DELETE: DELETE /products/:id -->router.delete('/:id', async (req, res) => { try { const product = await Product.findByIdAndDelete(req.params.id); if (!product) { return res.status(404).json({ error: 'Product not found' }); } res.status(204).send(); } catch (err) { res.status(500).json({ error: err.message }); }});
module.exports = router;4. Main App File (app.js)
require('dotenv').config();const express = require('express');const connectDB = require('./config/db');const productRoutes = require('./routes/products');
<!-- Connect to database -->connectDB();
const app = express();app.use(express.json());
<!-- Routes -->app.use('/api/products', productRoutes);
<!-- 404 handler -->app.use((req, res) => { res.status(404).json({ error: 'Route not found' });});
<!-- Error handler -->app.use((err, req, res, next) => { console.error(err); res.status(500).json({ error: 'Internal server error' });});
const PORT = process.env.PORT || 3000;app.listen(PORT, () => { console.log(`Server running on port ${PORT}`);});Two Minute Drill
- CRUD = Create (POST), Read (GET), Update (PUT), Delete (DELETE).
- Always validate input and handle errors gracefully.
- Use appropriate HTTP status codes (201 for created, 404 for not found, etc.).
- Organize routes using Express Router for clean code.
- Test your API with tools like Postman or Insomnia.
Need more clarification?
Drop us an email at career@quipoinfotech.com
