This tutorial will guide you through building a RESTful API using Node.js, Express.js, and MongoDB. We’ll cover setting up your environment, defining API endpoints, and handling data persistence. By the end, you’ll have a functional API ready for expansion.
Table of Contents
- Introduction to REST APIs and MongoDB
- Setting up Your Development Environment
- Project Setup and Dependencies
- Connecting to MongoDB
- Defining API Endpoints (CRUD Operations)
- Testing Your API
- Implementing Robust Error Handling
- Conclusion and Next Steps
Introduction to REST APIs and MongoDB
REST (Representational State Transfer) is an architectural style for building scalable and maintainable web services. REST APIs use standard HTTP methods (GET, POST, PUT, DELETE) to interact with resources identified by URLs. MongoDB is a NoSQL, document-oriented database that provides flexibility for storing and retrieving data. This combination creates a powerful foundation for many applications.
Setting up Your Development Environment
Before we begin, ensure you have Node.js and npm (Node Package Manager) installed. You can download them from nodejs.org. Also, ensure MongoDB is installed and running. You can download it from mongodb.com.
Project Setup and Dependencies
Create a new project directory and navigate to it in your terminal. Initialize a new Node.js project:
npm init -y
Install the necessary dependencies:
npm install express mongoose body-parser
express
: A minimal and flexible Node.js web application framework.mongoose
: An Object Data Modeling (ODM) library for MongoDB and Node.js.body-parser
: Middleware to parse JSON request bodies.
Connecting to MongoDB
Create a file named server.js
and add the following code:
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const app = express();
const port = 3000;
// MongoDB connection string - replace with your connection details
const mongoURI = 'mongodb://localhost:27017/mydatabase';
mongoose.connect(mongoURI, { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => console.log('Connected to MongoDB'))
.catch(err => console.error('Error connecting to MongoDB:', err));
app.use(bodyParser.json());
app.listen(port, () => console.log(`Server listening on port ${port}`));
Defining API Endpoints (CRUD Operations)
Let’s create a simple model and endpoints for managing items. Add this to your server.js
file:
const ItemSchema = new mongoose.Schema({
name: String,
description: String
});
const Item = mongoose.model('Item', ItemSchema);
// POST /items - Create a new item
app.post('/items', async (req, res) => {
try {
const newItem = new Item(req.body);
const savedItem = await newItem.save();
res.status(201).json(savedItem);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// GET /items - Get all items
app.get('/items', async (req, res) => {
try {
const items = await Item.find({});
res.json(items);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// GET /items/:id - Get a single item by ID
app.get('/items/:id', async (req, res) => {
try {
const item = await Item.findById(req.params.id);
if (!item) return res.status(404).json({ message: 'Item not found' });
res.json(item);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// PUT /items/:id - Update an item
app.put('/items/:id', async (req, res) => {
try {
const updatedItem = await Item.findByIdAndUpdate(req.params.id, req.body, { new: true });
if (!updatedItem) return res.status(404).json({ message: 'Item not found' });
res.json(updatedItem);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// DELETE /items/:id - Delete an item
app.delete('/items/:id', async (req, res) => {
try {
const deletedItem = await Item.findByIdAndDelete(req.params.id);
if (!deletedItem) return res.status(404).json({ message: 'Item not found' });
res.json({ message: 'Item deleted' });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
Testing Your API
Use tools like Postman or curl to test your API endpoints. Send POST requests to /items
to create new items, GET requests to /items
to retrieve all items, and use GET, PUT, and DELETE requests for individual items using their IDs.
Implementing Robust Error Handling
The example code includes basic error handling. For production, implement more comprehensive error handling, logging, and input validation.
Conclusion and Next Steps
You’ve successfully built a basic REST API with MongoDB! Expand this by adding authentication, authorization, data validation, and more sophisticated error handling. Consider using a production-ready database connection and explore more advanced features of both Express.js and Mongoose.