3.1Express : routes, middlewares, requêtes & réponses
L'essentiel en 30 secondes
- Express affine le module http : routage propre (app.get/post/put/delete), paramètres dynamiques (/users/:id → req.params.id), réponses en une ligne (res.json).
- Le middleware est le concept clé : une fonction (req, res, next) que chaque requête traverse ; elle agit puis appelle next() ou répond pour arrêter la chaîne.
- L'ordre du pipeline compte : parser d'abord (express.json()), valider et authentifier ensuite, répondre en dernier avec le bon statut.
Mini-cas filé — Salim remplace sa cascade de if par Express
Salim, développeur junior à Alger, sert un mini-catalogue avec le module http natif : une cascade de if sur req.url et req.method, un corps POST parsé à la main, des en-têtes posés un par un. Il réécrit le tout avec Express : app.use(express.json()) pour parser le corps, app.get('/produits/:id') pour les fiches dynamiques, un middleware qui journalise chaque requête, res.status(201).json() pour les créations. Même serveur, code trois fois plus lisible.
Ce même cas revient dans le cours, le schéma, le script et le défi 48h.
1. Routage & req/res enrichis
Express est le framework web de référence de Node : minimaliste, flexible, bâti sur le module http (section 2-4). Le routage associe une méthode HTTP et une URL à un handler : app.get('/users', handler), app.post('/users', handler), et pareil pour put, patch et delete. Les routes dynamiques capturent des segments : app.get('/users/:id') rend l'identifiant lisible dans req.params.id.
Les objets sont enrichis par rapport au natif. Côté requête : req.params (paramètres de route), req.query (query string après le ?), req.body (corps parsé, disponible grâce à express.json()). Côté réponse : res.json(data) envoie du JSON en une méthode, res.status(201).json(...) fixe le statut puis envoie, res.send et res.redirect couvrent les autres cas. Salim y gagne l'essentiel : plus de parsing manuel, des routes lisibles, des réponses explicites.
2. Le middleware : un pipeline où l'ordre compte
Le middleware est LE concept clé d'Express : une fonction (req, res, next) qui s'exécute pendant le traitement d'une requête. Elle peut inspecter ou modifier req et res (attacher req.user après authentification), exécuter du code (journaliser, valider, mesurer), puis appeler next() pour passer au middleware suivant — ou envoyer une réponse pour arrêter la chaîne (par exemple renvoyer 401 sans aller plus loin).
Chaque requête traverse un pipeline dans l'ordre de déclaration : express.json() qui parse le corps, vos middlewares (log, auth, validation), puis le handler final qui répond. Tout est middleware : parsing, fichiers statiques, auth, gestion d'erreurs. Deux réflexes de Salim : parser avant de valider (sinon req.body est vide) et toujours appeler next() ou répondre (sinon la requête reste bloquée). On applique un middleware globalement (app.use(...)) ou sur une route précise.
Le chaînon manquant
Un middleware qui ne passe pas la main bloque tout le monde.
🔎 Exemple concret — Une mini-API catalogue en quelques lignes
Salim réécrit son serveur natif avec Express.
const express = require('express');
const app = express();
app.use(express.json());
app.use((req, res, next) => { console.log(req.method, req.url); next(); });
app.get('/produits/:id', (req, res) => res.json({ id: req.params.id }));
app.post('/produits', (req, res) => res.status(201).json(req.body));
app.listen(3000);
Lecture : le logger appelle next(), la route dynamique lit req.params, la création renvoie 201.
Leçon : le parsing automatique supprime tout le code manuel du serveur natif.
Vocabulaire de la section
- Express
- Framework web minimaliste de référence pour Node, bâti sur le module http ; apporte routage, middlewares et req/res enrichis.
Exemple simple : Salim y réécrit son catalogue en quelques lignes lisibles.
Ce que ce n'est pas : un remplaçant de Node qui se passerait du module http.
Réflexe : l'utiliser pour toute API ou appli web plutôt que le natif brut.
- Routage
- Association d'une méthode HTTP et d'une URL à un handler : app.get('/users', ...), app.post(...), avec routes dynamiques '/users/:id'.
Exemple simple : GET /produits/7 capturé par app.get('/produits/:id').
Ce que ce n'est pas : une cascade de if sur req.url dans un serveur natif.
Réflexe : une route par intention, avec le bon verbe HTTP.
- Middleware
- Fonction (req, res, next) exécutée pendant le traitement ; agit sur req/res puis appelle next() ou envoie une réponse.
Exemple simple : Le logger de Salim qui note chaque requête puis passe la main.
Ce que ce n'est pas : une simple fonction utilitaire jamais branchée sur le pipeline.
Réflexe : toujours terminer par next() ou par une réponse.
- Pipeline de middlewares
- Chaîne ordonnée de middlewares que chaque requête traverse : parsing, log, auth, validation, handler final.
Exemple simple : express.json() puis validation puis handler chez Salim.
Ce que ce n'est pas : des handlers isolés sans ordre ni partage.
Réflexe : parser d'abord, valider ensuite, répondre en dernier.
- req / res enrichis
- Objets Express : req.params, req.query, req.body côté requête ; res.json, res.status, res.send, res.redirect côté réponse.
Exemple simple : req.params.id lu et res.status(201).json() renvoyé.
Ce que ce n'est pas : le req/res brut du module http sans aide.
Réflexe : lire le corps dans req.body, répondre avec res.json().
En pratique — Construire une application avec Express
- Créez une app Express (const app = express()), ajoutez app.use(express.json()) pour parser le JSON, et démarrez avec app.listen(3000).
- Définissez des routes : app.get('/users', ...), app.post('/users', ...), et une route dynamique app.get('/users/:id', ...) (lisez req.params.id).
- Renvoyez des réponses avec les méthodes enrichies : res.json(data), res.status(201).json(...), et lisez le corps avec req.body.
- Écrivez votre propre middleware (req, res, next) qui journalise chaque requête, appliquez-le avec app.use(...) et appelez next().
Script prêt à dire — présenter son API Express (30 s)
« J'ai monté l'API catalogue avec Express : express.json pour parser le corps, une route dynamique /produits/:id lue dans req.params, un middleware qui journalise puis appelle next, et des réponses res.json avec le bon statut, 201 pour les créations. Testé au navigateur sur localhost:3000. »
À dire en revue ; montrer la route dynamique et le log d'une requête.
Modèle copier-coller — serveur Express minimal
const express = require('express');
const app = express();
app.use(express.json());
app.use((req, res, next) => {
console.log(req.method, req.url);
next();
});
app.get('/produits/:id', (req, res) => {
res.json({ id: req.params.id });
});
app.post('/produits', (req, res) => {
res.status(201).json(req.body);
});
app.listen(3000, () => console.log('OK port 3000'));
Indépendant
Une API devis en Express suffit : deux routes GET/POST et un middleware de log, sans framework lourd.
PME à Alger
Salim expose le catalogue interne : routes dynamiques par référence produit, statuts 200/201/404 respectés.
Équipe produit
Standardiser le pipeline (json, log, auth, validation) pour que chaque route hérite du même socle.
Débutant
Cette semaine : un seul serveur, une route GET dynamique et un middleware qui appelle next().
✓ Bonnes pratiques
- Penser « pipeline » : tout est middleware, l'ordre compte.
- Utiliser express.json() pour parser le corps, et res.json() pour répondre.
- Encapsuler les préoccupations transversales (auth, log) en middlewares réutilisables.
✗ Pièges fréquents
- Oublier d'appeler next() (la requête reste bloquée).
- Mal ordonner les middlewares (valider avant de parser).
- Mettre toute la logique dans un seul handler au lieu de composer des middlewares.
Points clés à retenir
- EXPRESS = framework web de référence de Node (bâti sur http) : simplifie routage, parsing et gestion des requêtes.
- ROUTAGE : app.get/post/put/delete('/chemin', handler) ; routes dynamiques /users/:id → req.params.id.
- Le MIDDLEWARE (req, res, next) est LE concept clé : il agit pendant le traitement, puis next() passe au suivant — un PIPELINE.
- Tout est middleware : express.json(), static, auth, gestion d'erreurs, vos propres middlewares (app.use ou par route).
Défi 48h — appliquez demain
Montez 1 API Express avec 1 route dynamique et 1 middleware de log qui appelle next().
- Je cite le rôle de next() sans hésiter.
- Je lis req.params, req.query et req.body.
- Mon API répond res.json() avec le bon statut.
Questions fréquentes
Qu'est-ce qu'un middleware exactement, et pourquoi est-ce le concept central d'Express ?
Un middleware est une fonction (req, res, next) qui s'exécute pendant le traitement d'une requête. Il peut inspecter la requête, modifier req/res (par exemple attacher req.user), exécuter du code (journaliser, valider), puis décider : appeler next() pour passer au suivant, ou envoyer une réponse pour arrêter la chaîne (un middleware d'auth qui renvoie 401). C'est central parce que tout est middleware dans Express : parsing (express.json()), statique, auth, validation, gestion d'erreurs — et vos handlers de route sont le dernier maillon. Penser « pipeline ordonné » plutôt que « fonctions isolées », c'est comprendre Express.
Pourquoi Express est-il si populaire, et existe-t-il des alternatives ?
Minimaliste et non-opinioné (routage + middlewares, liberté de structure), simple à démarrer, mature et éprouvé, écosystème immense de middlewares et standard de facto attendu d'un développeur Node. Ses limites (choix à faire soi-même, pas de structure imposée) motivent des alternatives comme Fastify, Koa ou NestJS sur les gros projets. Mais pour apprendre puis produire vite, Express reste le choix par défaut — celui que Salim maîtrise en premier à Alger.
Dans un middleware Express, qu'impose le contrat (req, res, next) ?