Building a REST API with Node.js and Express
Creating a RESTful API is a common task for web developers. In this tutorial, we'll build a simple REST API using Node.js and Express.
Setting Up the Project
First, create a new directory for your project and initialize it:
mkdir my-rest-api
cd my-rest-api
npm init -y
Install the necessary packages:
npm install express mongoose cors dotenv
Creating the Server
Create an index.js
file to set up your Express server:
const express = require('express');
const cors = require('cors');
require('dotenv').config();
const app = express();
const PORT = process.env.PORT || 5000;
// Middleware
app.use(cors());
app.use(express.json());
// Basic route
app.get('/', (req, res) => {
res.json({ message: 'Welcome to the REST API' });
});
// Start server
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
Connecting to MongoDB
Let's add MongoDB connection with Mongoose:
const mongoose = require('mongoose');
mongoose.connect(process.env.MONGODB_URI)
.then(() => console.log('Connected to MongoDB'))
.catch(err => console.error('Could not connect to MongoDB', err));
Creating a Model
Create a models
directory and add a file for your model, for example product.model.js
:
const mongoose = require('mongoose');
const productSchema = new mongoose.Schema({
name: {
type: String,
required: true,
trim: true
},
description: {
type: String,
required: true
},
price: {
type: Number,
required: true,
min: 0
},
category: {
type: String,
required: true
},
createdAt: {
type: Date,
default: Date.now
}
});
module.exports = mongoose.model('Product', productSchema);
Creating Routes
Create a routes
directory and add a file for your routes, for example product.routes.js
:
const express = require('express');
const router = express.Router();
const Product = require('../models/product.model');
// Get all products
router.get('/', async (req, res) => {
try {
const products = await Product.find();
res.json(products);
} catch (err) {
res.status(500).json({ message: err.message });
}
});
// Get one product
router.get('/:id', getProduct, (req, res) => {
res.json(res.product);
});
// Create a product
router.post('/', async (req, res) => {
const product = new Product({
name: req.body.name,
description: req.body.description,
price: req.body.price,
category: req.body.category
});
try {
const newProduct = await product.save();
res.status(201).json(newProduct);
} catch (err) {
res.status(400).json({ message: err.message });
}
});
// Update a product
router.patch('/:id', getProduct, async (req, res) => {
if (req.body.name != null) {
res.product.name = req.body.name;
}
if (req.body.description != null) {
res.product.description = req.body.description;
}
if (req.body.price != null) {
res.product.price = req.body.price;
}
if (req.body.category != null) {
res.product.category = req.body.category;
}
try {
const updatedProduct = await res.product.save();
res.json(updatedProduct);
} catch (err) {
res.status(400).json({ message: err.message });
}
});
// Delete a product
router.delete('/:id', getProduct, async (req, res) => {
try {
await res.product.remove();
res.json({ message: 'Product deleted' });
} catch (err) {
res.status(500).json({ message: err.message });
}
});
// Middleware to get product by ID
async function getProduct(req, res, next) {
let product;
try {
product = await Product.findById(req.params.id);
if (product == null) {
return res.status(404).json({ message: 'Cannot find product' });
}
} catch (err) {
return res.status(500).json({ message: err.message });
}
res.product = product;
next();
}
module.exports = router;
Connecting Routes to the Server
Update your index.js
to use the routes:
// Import routes
const productRoutes = require('./routes/product.routes');
// Use routes
app.use('/api/products', productRoutes);
Testing the API
You can test your API using tools like Postman or by writing simple HTTP requests using a library like axios or fetch.
Conclusion
Congratulations! You've built a basic REST API with Node.js and Express. You can extend this API by adding authentication, validation, and more complex endpoints to suit your application's needs.