Nodejs
Express
Api
Rest
Guide pratique pour initialiser un projet NodeJS avec Express, en configurant les routes, middlewares et la structure de base.
Objectif de l'article
Guide pratique pour initialiser un projet NodeJS avec Express, en configurant les routes, middlewares et la structure de base.
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