- Express.js Basics
- Express.js HOME
- Express.js Introduction
- Express.js Installation
- Express.js Basic App
- Express.js Routing
- Basics Routing
- Route Parameters
- Handling Query Strings
- Router Middleware
- Middleware
- What is Middleware?
- Application-Level Middleware
- Router-Level Middleware
- Built-In Middleware
- Error-Handling Middleware
- Third-Party Middleware
- Express.js HTTP
- Handling GET Requests
- Handling POST Requests
- Handling PUT Requests
- Handling DELETE Requests
- Templating Engines
- Using Templating Engines
- Setting Up EJS
- Setting Up Handlebars
- Setting Up Pug
- Request/Response
- Request Object
- Response Object
- Handling JSON Data
- Handling Form Data
- Static Files
- Serving Static Files
- Setting Up Static Folders
- Managing Assets
- Express.js Advanced
- Middleware Stack
- CORS in Express.js
- JWT Authentication
- Session Handling
- File Uploads
- Error Handling
- Databases
- Express.js with MongoDB
- MongoDB CRUD Operations
- Express.js with MySQL
- MySQL CRUD Operations
- Deployment
- Deploying Express.js Apps to Heroku
- Deploying Express.js Apps to AWS
- Deploying Express.js Apps to Vercel
Express.js MongoDB CRUD Operations
CRUD operations (Create, Read, Update, and Delete) are the essential building blocks of any data-driven application. Whether you are building a social media platform, an e-commerce site, or a simple task manager, you will need to interact with a database. By combining Express.js with MongoDB (using the Mongoose library), developers can create powerful APIs that manage data with minimal friction. This guide walks you through the implementation of these core operations in a modern Node.js environment.
Key Features of MongoDB CRUD Operations
- Create: The process of validating and saving new data "documents" into your MongoDB collections.
- Read: Querying the database to retrieve specific records or lists of data based on various criteria.
- Update: Modifying existing documents in the database, ranging from changing a single field to replacing entire objects.
- Delete: Safely removing records from the database when they are no longer needed.
Setting Up CRUD Operations with MongoDB
Install Dependencies
To get started, you need to install the Express framework and Mongoose. Mongoose is an ODM (Object Data Modeling) library that provides a straight-forward, schema-based solution to model your application data.
npm install express mongoose
MongoDB Connection
Establish a connection to your MongoDB instance. In a real-world scenario, you might use MongoDB Atlas (cloud) or a local installation.
const mongoose = require('mongoose');
// Replace the URL with your actual connection string
mongoose.connect('mongodb://localhost:27017/mydatabase')
.then(() => console.log('Successfully connected to MongoDB'))
.catch(err => console.error('Database connection error:', err));
Define a Schema and Model
Because MongoDB is "schema-less," Mongoose allows us to define a structure at the application level. This ensures that every user saved to your database follows the same format.
const userSchema = new mongoose.Schema({
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
age: Number,
createdAt: { type: Date, default: Date.now }
});
const User = mongoose.model('User', userSchema);
required: true). This prevents "dirty data" from entering your database and saves you from writing complex validation logic in your routes.
CRUD Operations
1. Create (Insert Data)
To add data, we typically use an HTTP POST request. We take the data from the request body, create a new instance of our Model, and call .save().
app.post('/add-user', async (req, res) => {
try {
const user = new User(req.body);
await user.save();
res.status(201).send('User created successfully');
} catch (err) {
res.status(400).send('Error creating user: ' + err.message);
}
});
2. Read (Fetch Data)
The find() method is used to retrieve documents. You can fetch everything in a collection or filter the results by passing an object to the query.
app.get('/users', async (req, res) => {
try {
const users = await User.find(); // Returns an array of all users
res.json(users);
} catch (err) {
res.status(500).send('Server error: ' + err.message);
}
});
find() returns an empty array [] if no documents match, not an error. Always check the length of the result if you need to handle "not found" scenarios.
3. Update (Modify Data)
To update, we use the findByIdAndUpdate method. This is efficient because it targets a specific document by its unique _id.
app.put('/update-user/:id', async (req, res) => {
try {
// { new: true } returns the modified document rather than the original
const user = await User.findByIdAndUpdate(req.params.id, req.body, { new: true, runValidators: true });
if (!user) return res.status(404).send('User not found');
res.json(user);
} catch (err) {
res.status(400).send('Update failed: ' + err.message);
}
});
{ runValidators: true } in the options if you want to enforce your schema rules during updates.
4. Delete (Remove Data)
Deleting a document is straightforward with findByIdAndDelete. This is usually handled via an HTTP DELETE request.
app.delete('/delete-user/:id', async (req, res) => {
try {
const user = await User.findByIdAndDelete(req.params.id);
if (!user) return res.status(404).send('User not found');
res.send('User deleted successfully');
} catch (err) {
res.status(500).send('Delete failed: ' + err.message);
}
});
Complete Example for CRUD Operations
Here is how all these pieces fit together into a single app.js file. This example uses modern Express middleware to parse incoming JSON data.
const express = require('express');
const mongoose = require('mongoose');
const app = express();
app.use(express.json()); // Built-in middleware to parse JSON
// MongoDB connection
mongoose.connect('mongodb://localhost:27017/mydatabase');
// Schema and model
const userSchema = new mongoose.Schema({
name: String,
email: String,
age: Number
});
const User = mongoose.model('User', userSchema);
// CREATE: Add a user
app.post('/add-user', async (req, res) => {
const user = new User(req.body);
try {
await user.save();
res.status(201).json({ message: 'User added successfully', user });
} catch (err) {
res.status(400).json({ error: err.message });
}
});
// READ: Get all users
app.get('/users', async (req, res) => {
try {
const users = await User.find();
res.json(users);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// UPDATE: Update user by ID
app.put('/update-user/:id', async (req, res) => {
try {
const user = await User.findByIdAndUpdate(req.params.id, req.body, { new: true });
if (!user) return res.status(404).send('User not found');
res.json(user);
} catch (err) {
res.status(400).json({ error: err.message });
}
});
// DELETE: Remove user by ID
app.delete('/delete-user/:id', async (req, res) => {
try {
const user = await User.findByIdAndDelete(req.params.id);
if (!user) return res.status(404).send('User not found');
res.send('User deleted successfully');
} catch (err) {
res.status(500).json({ error: err.message });
}
});
const PORT = 3000;
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
Summary
Implementing CRUD operations with Express.js and MongoDB provides a robust foundation for building modern APIs. By leveraging Mongoose, you gain the benefits of structured data within a flexible NoSQL environment. Remember to always handle your errors gracefully and use proper HTTP status codes (like 201 for Created or 404 for Not Found) to make your API predictable and professional for other developers to use.