Node-Js
Express
Api
Rest
Rest-Api
Javascript
Backend
Middleware
Routing
Validation
Error-Handling
Structure-Projet
Mvc
Npm
Construisez une API REST avec Node.js et Express : configuration des routes, middlewares d'authentification, gestion des erreurs et structure de projet propre.
Objectif de l'article
Construisez une API REST avec Node.js et Express : configuration des routes, middlewares d'authentification, gestion des erreurs et structure de projet propre.
A retenir: avance par itération, mesure les impacts, puis industrialise.
Concepts clés
Avant de démarrer votre projet Express, voici les concepts fondamentaux à maîtriser :
- Node.js : runtime JavaScript côté serveur, asynchrone et event-driven
- Express : framework léger et flexible pour créer des serveurs HTTP et des APIs REST
- Routes : chemins HTTP (GET, POST, PUT, DELETE) qui mappent à des contrôleurs
- Middlewares : fonctions qui traitent les requêtes avant d'atteindre les routes
- RESTful : convention de conception utilisant les verbes HTTP pour manipuler des ressources
- JSON : format de données standard pour les APIs modernes
- npm : gestionnaire de paquets pour gérer les dépendances Node.js
Implémentation
Étape 1 : Initialiser le projet
Créez un dossier pour votre projet et initialisez npm :
mkdir mon-api-express
cd mon-api-express
npm init -y
npm install express cors dotenv
Étape 2 : Créer le serveur principal
Créez un fichier server.js à la racine :
const express = require('express');
const cors = require('cors');
require('dotenv').config();
const app = express();
const PORT = process.env.PORT || 3000;
// Middlewares globaux
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// Routes
app.get('/api/health', (req, res) => {
res.json({ status: 'OK', timestamp: new Date() });
});
// Gestion des erreurs 404
app.use((req, res) => {
res.status(404).json({ error: 'Route non trouvée' });
});
// Démarrer le serveur
app.listen(PORT, () => {
console.info(`Serveur lancé sur http://localhost:${PORT}`);
});
Étape 3 : Créer une structure modulaire avec des routes
Créez un dossier routes et ajoutez un fichier products.js :
const express = require('express');
const router = express.Router();
// Données exemple
let products = [
{ id: 1, name: 'Produit 1', price: 29.99 },
{ id: 2, name: 'Produit 2', price: 49.99 }
];
// GET tous les produits
router.get('/', (req, res) => {
res.json(products);
});
// GET un produit par ID
router.get('/:id', (req, res) => {
const product = products.find(p => p.id === parseInt(req.params.id));
if (!product) {
return res.status(404).json({ error: 'Produit non trouvé' });
}
res.json(product);
});
// POST créer un produit
router.post('/', (req, res) => {
const { name, price } = req.body;
if (!name || !price) {
return res.status(400).json({ error: 'name et price sont requis' });
}
const newProduct = {
id: Math.max(...products.map(p => p.id), 0) + 1,
name,
price
};
products.push(newProduct);
res.status(201).json(newProduct);
});
// PUT mettre à jour un produit
router.put('/:id', (req, res) => {
const product = products.find(p => p.id === parseInt(req.params.id));
if (!product) {
return res.status(404).json({ error: 'Produit non trouvé' });
}
if (req.body.name) product.name = req.body.name;
if (req.body.price) product.price = req.body.price;
res.json(product);
});
// DELETE supprimer un produit
router.delete('/:id', (req, res) => {
const index = products.findIndex(p => p.id === parseInt(req.params.id));
if (index === -1) {
return res.status(404).json({ error: 'Produit non trouvé' });
}
const deleted = products.splice(index, 1);
res.json(deleted[0]);
});
module.exports = router;
Étape 4 : Intégrer les routes dans server.js
const productRoutes = require('./routes/products');
// Intégrer les routes
app.use('/api/products', productRoutes);
Étape 5 : Créer un middleware personnalisé
Créez un fichier middlewares/logger.js :
const logger = (req, res, next) => {
console.info(`${new Date().toISOString()} - ${req.method} ${req.path}`);
next();
};
module.exports = logger;
Utilisez-le dans votre serveur :
const logger = require('./middlewares/logger');
app.use(logger);
Étape 6 : Ajouter des variables d'environnement
Créez un fichier .env :
PORT=3000
NODE_ENV=development
DB_URL=mongodb://localhost:27017/mon-api
Et un fichier .env.example pour la documentation :
PORT=3000
NODE_ENV=development
DB_URL=mongodb://localhost:27017/mon-api
Intégration en production
Bonnes pratiques de sécurité
- Valider les entrées : Toujours valider et nettoyer les données reçues
- Gérer les erreurs : Ne pas exposer les détails internes des erreurs
- HTTPS obligatoire : Utiliser HTTPS en production (certificat SSL/TLS)
- Rate limiting : Limiter le nombre de requêtes par client avec un middleware
- CORS configuré : Définir les origines autorisées, pas * en production
- Authentication : Implémenter JWT ou sessions sécurisées
- Logging sécurisé : Logger les erreurs sans exposer les secrets
Exemple de gestion d'erreurs centralisée
// Middleware de gestion d'erreurs (à la fin de server.js)
app.use((err, req, res, next) => {
console.error(err.stack);
const status = err.status || 500;
const message = process.env.NODE_ENV === 'production'
? 'Erreur serveur'
: err.message;
res.status(status).json({ error: message });
});
Lancer l'application en production
- Utiliser un process manager comme PM2
- Configurer les variables d'environnement pour la prod
- Mettre en place un reverse proxy (Nginx) devant Express
- Configurer les logs et la surveillance (monitoring)
- Utiliser Docker pour standardiser l'environnement
- Automatiser le déploiement avec CI/CD
Installer et lancer avec PM2
npm install -g pm2
pm2 start server.js --name "mon-api"
pm2 save
pm2 startup
Configuration Nginx exemple
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Tester votre API
Utilisez curl ou Postman pour tester :
# GET tous les produits
curl http://localhost:3000/api/products
# POST créer un produit
curl -X POST http://localhost:3000/api/products \
-H "Content-Type: application/json" \
-d '{"name":"Nouveau produit","price":99.99}'
# GET un produit
curl http://localhost:3000/api/products/1
# PUT mettre à jour
curl -X PUT http://localhost:3000/api/products/1 \
-H "Content-Type: application/json" \
-d '{"name":"Produit modifié"}'
# DELETE
curl -X DELETE http://localhost:3000/api/products/1
Prochaines étapes
- Ajouter une base de données (MongoDB, PostgreSQL)
- Implémenter l'authentification JWT
- Créer des tests unitaires avec Jest
- Ajouter la validation avec Joi ou Zod
- Mettre en place une documentation Swagger/OpenAPI