Table of Contents
- Introduction to Express and MongoDB Integration
- Setting Up MongoDB with Express
- Installing Dependencies
- Setting Up the MongoDB Database Connection
- Defining the Schema and Model
- Creating Basic CRUD Operations
- Create Operation (
POST
) - Read Operation (
GET
) - Update Operation (
PUT
) - Delete Operation (
DELETE
)
- Create Operation (
- Testing the REST API
- Error Handling and Validation
- Conclusion
1. Introduction to Express and MongoDB Integration
Express is a lightweight and flexible web application framework for Node.js. MongoDB, on the other hand, is a NoSQL database that stores data in a flexible, JSON-like format called BSON. Integrating MongoDB with Express allows you to build dynamic and scalable web applications that can handle large volumes of data with ease.
In this article, we will learn how to integrate MongoDB with an Express application to create a basic REST API that performs CRUD operations (Create, Read, Update, Delete).
2. Setting Up MongoDB with Express
Before we begin coding, ensure that you have the following prerequisites in place:
- Node.js and npm installed on your machine.
- MongoDB running locally or using a cloud service like MongoDB Atlas.
- A code editor like VS Code.
3. Installing Dependencies
To set up the integration between Express and MongoDB, we need a few dependencies:
- Express: The web application framework.
- Mongoose: An Object Data Modeling (ODM) library for MongoDB and Node.js, which simplifies interacting with MongoDB by providing a schema-based solution.
- Body-Parser: Middleware to parse incoming request bodies.
You can install these dependencies via npm by running the following command:
bashCopyEditnpm install express mongoose body-parser
4. Setting Up the MongoDB Database Connection
Now that we have our dependencies installed, the next step is to connect to MongoDB using Mongoose. Create a file named server.js
or app.js
(or any name you prefer) and set up your Express server.
Example Code for Connecting to MongoDB
jsCopyEditconst express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const app = express();
// Middleware to parse JSON data
app.use(bodyParser.json());
// MongoDB connection string (Local or MongoDB Atlas URI)
const dbURI = 'mongodb://localhost:27017/myDatabase'; // Use your MongoDB URI
mongoose.connect(dbURI, { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => {
console.log('Connected to MongoDB');
})
.catch((err) => {
console.log('Error connecting to MongoDB:', err);
});
In this code:
- We use
mongoose.connect()
to establish a connection to the database. useNewUrlParser: true
anduseUnifiedTopology: true
are configuration options to avoid deprecation warnings.body-parser.json()
is middleware that ensures we can parse JSON payloads sent to our API.
5. Defining the Schema and Model
With the database connection established, we now define the data structure. In MongoDB, data is stored as documents within collections. Mongoose provides an elegant way to model data using Schemas and Models.
Let’s say we are building a simple Todo API. We will define a schema for the todo tasks.
Example: Defining a Todo Schema
jsCopyEditconst mongoose = require('mongoose');
const todoSchema = new mongoose.Schema({
title: { type: String, required: true },
description: { type: String, required: true },
completed: { type: Boolean, default: false },
createdAt: { type: Date, default: Date.now },
});
// Create a model based on the schema
const Todo = mongoose.model('Todo', todoSchema);
module.exports = Todo;
In this code, we define a Todo schema with the following fields:
- title: A required string field for the title of the task.
- description: A required string field for the task description.
- completed: A boolean field indicating whether the task is completed, with a default value of
false
. - createdAt: A date field with a default value of the current date and time.
6. Creating Basic CRUD Operations
Now that we have our model defined, let’s set up the CRUD operations (Create, Read, Update, and Delete) for our Todo API.
Create Operation (POST
)
To create a new todo item, we use the POST
method. Here’s the route to handle the creation of a new todo.
jsCopyEditapp.post('/todos', async (req, res) => {
const { title, description } = req.body;
try {
const todo = new Todo({
title,
description,
});
const savedTodo = await todo.save();
res.status(201).json(savedTodo);
} catch (error) {
res.status(400).json({ message: 'Error creating Todo' });
}
});
Read Operation (GET
)
To fetch all todo items, we use the GET
method.
jsCopyEditapp.get('/todos', async (req, res) => {
try {
const todos = await Todo.find();
res.status(200).json(todos);
} catch (error) {
res.status(400).json({ message: 'Error fetching Todos' });
}
});
To fetch a specific todo by ID, we can modify the route:
jsCopyEditapp.get('/todos/:id', async (req, res) => {
const { id } = req.params;
try {
const todo = await Todo.findById(id);
if (!todo) {
return res.status(404).json({ message: 'Todo not found' });
}
res.status(200).json(todo);
} catch (error) {
res.status(400).json({ message: 'Error fetching Todo' });
}
});
Update Operation (PUT
)
To update a todo item, we use the PUT
method. This allows the user to update the fields of an existing todo item.
jsCopyEditapp.put('/todos/:id', async (req, res) => {
const { id } = req.params;
const { title, description, completed } = req.body;
try {
const updatedTodo = await Todo.findByIdAndUpdate(
id,
{ title, description, completed },
{ new: true } // Returns the updated document
);
if (!updatedTodo) {
return res.status(404).json({ message: 'Todo not found' });
}
res.status(200).json(updatedTodo);
} catch (error) {
res.status(400).json({ message: 'Error updating Todo' });
}
});
Delete Operation (DELETE
)
To delete a todo item, we use the DELETE
method.
jsCopyEditapp.delete('/todos/:id', async (req, res) => {
const { id } = req.params;
try {
const deletedTodo = await Todo.findByIdAndDelete(id);
if (!deletedTodo) {
return res.status(404).json({ message: 'Todo not found' });
}
res.status(200).json({ message: 'Todo deleted' });
} catch (error) {
res.status(400).json({ message: 'Error deleting Todo' });
}
});
7. Testing the REST API
To test our API, we can use Postman or cURL to send requests to the server. Make sure your MongoDB server is running and the Express server is listening on a port (usually 3000
).
8. Error Handling and Validation
When building REST APIs, proper error handling and input validation are critical. You can enhance your API by validating incoming data before performing any operations.
For example, you can ensure that required fields are present before saving a new todo item:
jsCopyEditapp.post('/todos', async (req, res) => {
const { title, description } = req.body;
if (!title || !description) {
return res.status(400).json({ message: 'Title and Description are required' });
}
// Proceed with the rest of the logic
});
9. Conclusion
Integrating MongoDB with Express allows developers to build efficient and scalable REST APIs. Using Mongoose as an ORM simplifies working with MongoDB by providing schema validation, powerful querying, and model-based interaction with MongoDB documents.