Building a RESTful API with Node.js and Express
In this tutorial, we'll walk through building a simple RESTful API using Node.js and Express. This example demonstrates how our enhanced styling for code blocks and images works.
Prerequisites
Before we begin, make sure you have the following installed:
- Node.js (v14 or later)
- npm (v6 or later)
- A code editor (VS Code recommended)
Setting Up the Project
Let's start by creating a new project directory and initializing it:
The above commands create a new directory for our project, initialize a new npm package, and install Express.
Project Structure
Here's how our project structure will look:
rest-api-example/
├── node_modules/
├── src/
│ ├── controllers/
│ │ └── userController.js
│ ├── models/
│ │ └── userModel.js
│ ├── routes/
│ │ └── userRoutes.js
│ └── server.js
├── package.json
└── package-lock.json
Creating the Server
First, let's create our main server file. Create a file at src/server.js
with the following code:
const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;
// Middleware
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// Routes
app.get('/', (req, res) => {
res.json({ message: 'Welcome to our API' });
});
// Import user routes
const userRoutes = require('./routes/userRoutes');
app.use('/api/users', userRoutes);
// Error handling middleware
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({
error: true,
message: 'Internal Server Error'
});
});
// Start server
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
module.exports = app;
Creating the User Model
Next, let's create a simple user model in src/models/userModel.js
:
// This is a simple in-memory model for demonstration
// In a real application, you would use a database
const users = [
{ id: 1, name: 'John Doe', email: '[email protected]' },
{ id: 2, name: 'Jane Smith', email: '[email protected]' }
];
class UserModel {
findAll() {
return Promise.resolve(users);
}
findById(id) {
const user = users.find(user => user.id === parseInt(id));
return Promise.resolve(user || null);
}
create(userData) {
const newUser = {
id: users.length + 1,
...userData
};
users.push(newUser);
return Promise.resolve(newUser);
}
update(id, userData) {
const index = users.findIndex(user => user.id === parseInt(id));
if (index === -1) return Promise.resolve(null);
const updatedUser = { ...users[index], ...userData };
users[index] = updatedUser;
return Promise.resolve(updatedUser);
}
delete(id) {
const index = users.findIndex(user => user.id === parseInt(id));
if (index === -1) return Promise.resolve(false);
users.splice(index, 1);
return Promise.resolve(true);
}
}
module.exports = new UserModel();
User Controller
Now, let's create a controller to handle the business logic in src/controllers/userController.js
:
const UserModel = require('../models/userModel');
class UserController {
async getAllUsers(req, res, next) {
try {
const users = await UserModel.findAll();
res.json(users);
} catch (error) {
next(error);
}
}
async getUserById(req, res, next) {
try {
const user = await UserModel.findById(req.params.id);
if (!user) {
return res.status(404).json({ message: 'User not found' });
}
res.json(user);
} catch (error) {
next(error);
}
}
async createUser(req, res, next) {
try {
const { name, email } = req.body;
if (!name || !email) {
return res.status(400).json({ message: 'Name and email are required' });
}
const newUser = await UserModel.create({ name, email });
res.status(201).json(newUser);
} catch (error) {
next(error);
}
}
async updateUser(req, res, next) {
try {
const updatedUser = await UserModel.update(req.params.id, req.body);
if (!updatedUser) {
return res.status(404).json({ message: 'User not found' });
}
res.json(updatedUser);
} catch (error) {
next(error);
}
}
async deleteUser(req, res, next) {
try {
const success = await UserModel.delete(req.params.id);
if (!success) {
return res.status(404).json({ message: 'User not found' });
}
res.status(204).end();
} catch (error) {
next(error);
}
}
}
module.exports = new UserController();
Defining Routes
Now let's set up our routes in src/routes/userRoutes.js
:
const express = require('express');
const router = express.Router();
const UserController = require('../controllers/userController');
// GET all users
router.get('/', UserController.getAllUsers);
// GET user by ID
router.get('/:id', UserController.getUserById);
// POST new user
router.post('/', UserController.createUser);
// PUT update user
router.put('/:id', UserController.updateUser);
// DELETE user
router.delete('/:id', UserController.deleteUser);
module.exports = router;
Testing the API
Let's test our API with some HTTP requests. You can use tools like Postman, curl, or even a simple fetch in the browser.
Here's a sample curl command to get all users:
Conclusion
We've built a simple RESTful API using Node.js and Express! This example demonstrates:
- Setting up an Express server
- Creating routes
- Implementing controllers
- Building a simple data model
In a real-world application, you would want to add:
- Database integration (MongoDB, PostgreSQL, etc.)
- Authentication and authorization
- Input validation
- Testing
- Documentation
Next Steps
Try extending this API with:
- Adding more endpoints
- Implementing search functionality
- Adding authentication with JWT
- Connecting to a real database
Happy coding!