Créer une API REST avec Express.js : Guide Pratique
Mark Toledo
8 janvier 2025

Express.js est le framework Node.js le plus populaire pour créer des API REST. Léger mais puissant, il offre tout ce qu'il faut pour construire des backends robustes. Ce guide vous accompagne dans la création d'une API complète.
Installation et configuration
Initialisation du projet
mkdir mon-api
cd mon-api
npm init -y
npm install express
npm install --save-dev nodemon
Configuration de base
// app.js
const express = require('express');
const app = express();
// Middleware pour parser le JSON
app.use(express.json());
// Route de test
app.get('/', (req, res) => {
res.json({ message: 'Bienvenue sur l\'API !' });
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Serveur démarré sur http://localhost:${PORT}`);
});
Ajoutez le script dans package.json :
{
"scripts": {
"start": "node app.js",
"dev": "nodemon app.js"
}
}
Les routes RESTful
Structure CRUD complète
// data.js - Données simulées
let utilisateurs = [
{ id: 1, nom: 'Alice', email: 'alice@exemple.fr' },
{ id: 2, nom: 'Bob', email: 'bob@exemple.fr' }
];
module.exports = { utilisateurs };
// routes/users.js
const express = require('express');
const router = express.Router();
const { utilisateurs } = require('../data');
// GET /api/users - Liste tous les utilisateurs
router.get('/', (req, res) => {
res.json(utilisateurs);
});
// GET /api/users/:id - Un utilisateur par ID
router.get('/:id', (req, res) => {
const id = parseInt(req.params.id);
const user = utilisateurs.find(u => u.id === id);
if (!user) {
return res.status(404).json({ error: 'Utilisateur non trouvé' });
}
res.json(user);
});
// POST /api/users - Créer un utilisateur
router.post('/', (req, res) => {
const { nom, email } = req.body;
if (!nom || !email) {
return res.status(400).json({ error: 'Nom et email requis' });
}
const newUser = {
id: utilisateurs.length + 1,
nom,
email
};
utilisateurs.push(newUser);
res.status(201).json(newUser);
});
// PUT /api/users/:id - Modifier un utilisateur
router.put('/:id', (req, res) => {
const id = parseInt(req.params.id);
const index = utilisateurs.findIndex(u => u.id === id);
if (index === -1) {
return res.status(404).json({ error: 'Utilisateur non trouvé' });
}
const { nom, email } = req.body;
utilisateurs[index] = { ...utilisateurs[index], nom, email };
res.json(utilisateurs[index]);
});
// DELETE /api/users/:id - Supprimer un utilisateur
router.delete('/:id', (req, res) => {
const id = parseInt(req.params.id);
const index = utilisateurs.findIndex(u => u.id === id);
if (index === -1) {
return res.status(404).json({ error: 'Utilisateur non trouvé' });
}
utilisateurs.splice(index, 1);
res.status(204).send();
});
module.exports = router;
Intégration dans l'application
// app.js
const express = require('express');
const usersRouter = require('./routes/users');
const app = express();
app.use(express.json());
// Monter les routes
app.use('/api/users', usersRouter);
// Route racine
app.get('/', (req, res) => {
res.json({
message: 'API REST avec Express',
endpoints: ['/api/users']
});
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`API démarrée sur http://localhost:${PORT}`);
});
Les Middlewares
Middleware de logging
// middlewares/logger.js
const logger = (req, res, next) => {
const timestamp = new Date().toISOString();
console.log(`[${timestamp}] ${req.method} ${req.url}`);
next();
};
module.exports = logger;
// Utilisation
app.use(logger);
Middleware d'authentification
// middlewares/auth.js
const authMiddleware = (req, res, next) => {
const token = req.headers.authorization;
if (!token) {
return res.status(401).json({ error: 'Token manquant' });
}
// Vérification simplifiée (utilisez JWT en production)
if (token !== 'Bearer mon-token-secret') {
return res.status(403).json({ error: 'Token invalide' });
}
// Ajouter l'utilisateur à la requête
req.user = { id: 1, role: 'admin' };
next();
};
module.exports = authMiddleware;
// Utilisation sur des routes spécifiques
router.get('/profile', authMiddleware, (req, res) => {
res.json({ user: req.user });
});
Middleware de gestion d'erreurs
// middlewares/errorHandler.js
const errorHandler = (err, req, res, next) => {
console.error(err.stack);
const statusCode = err.statusCode || 500;
const message = err.message || 'Erreur interne du serveur';
res.status(statusCode).json({
error: message,
...(process.env.NODE_ENV === 'development' && { stack: err.stack })
});
};
module.exports = errorHandler;
// Utilisation (doit être le dernier middleware)
app.use(errorHandler);
Validation des données
Validation manuelle
const validateUser = (req, res, next) => {
const { nom, email } = req.body;
const errors = [];
if (!nom || nom.length < 2) {
errors.push('Le nom doit contenir au moins 2 caractères');
}
if (!email || !email.includes('@')) {
errors.push('Email invalide');
}
if (errors.length > 0) {
return res.status(400).json({ errors });
}
next();
};
router.post('/', validateUser, (req, res) => {
// Logique de création...
});
Avec express-validator
npm install express-validator
const { body, validationResult } = require('express-validator');
const userValidationRules = [
body('nom')
.trim()
.isLength({ min: 2 })
.withMessage('Le nom doit contenir au moins 2 caractères'),
body('email')
.isEmail()
.normalizeEmail()
.withMessage('Email invalide')
];
const validate = (req, res, next) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
next();
};
router.post('/', userValidationRules, validate, (req, res) => {
// Création de l'utilisateur...
});
CORS et sécurité
npm install cors helmet
const cors = require('cors');
const helmet = require('helmet');
// Sécurité HTTP
app.use(helmet());
// CORS - Autoriser les requêtes cross-origin
app.use(cors({
origin: ['http://localhost:3000', 'https://monsite.fr'],
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization']
}));
Structure de projet recommandée
mon-api/
├── app.js # Point d'entrée
├── package.json
├── routes/
│ ├── index.js # Agrégateur de routes
│ ├── users.js
│ └── products.js
├── middlewares/
│ ├── auth.js
│ ├── logger.js
│ └── errorHandler.js
├── controllers/ # Logique métier
│ └── userController.js
├── models/ # Modèles de données
│ └── User.js
├── validators/ # Règles de validation
│ └── userValidator.js
└── config/
└── database.js
Bonnes pratiques
-
Codes HTTP appropriés : 200 (OK), 201 (Created), 204 (No Content), 400 (Bad Request), 401 (Unauthorized), 404 (Not Found), 500 (Server Error)
-
Versioning de l'API :
/api/v1/users -
Pagination pour les listes :
router.get('/', (req, res) => {
const page = parseInt(req.query.page) || 1;
const limit = parseInt(req.query.limit) || 10;
const startIndex = (page - 1) * limit;
const results = utilisateurs.slice(startIndex, startIndex + limit);
res.json({
data: results,
pagination: {
page,
limit,
total: utilisateurs.length,
pages: Math.ceil(utilisateurs.length / limit)
}
});
});
- Variables d'environnement :
npm install dotenv
require('dotenv').config();
const PORT = process.env.PORT || 3000;
Conclusion
Express.js offre une base solide pour créer des API REST professionnelles. Avec une bonne organisation, des middlewares bien pensés et une validation rigoureuse, vous pouvez construire des backends robustes et maintenables.
Dans les prochains articles, nous verrons comment connecter une base de données et implémenter l'authentification JWT.
