Express : routes
Méthodes HTTP
Section intitulée « Méthodes HTTP »import express from 'express';const app = express();
app.get('/clients', (req, res) => res.json([]));app.post('/clients', (req, res) => res.status(201).json({ id: 1 }));app.put('/clients/:id', (req, res) => res.json({ id: req.params.id }));app.patch('/clients/:id', (req, res) => res.json({ modifie: true }));app.delete('/clients/:id', (req, res) => res.sendStatus(204));app.all('/ping', (req, res) => res.send('pong')); // toutes les méthodesParamètres de chemin
Section intitulée « Paramètres de chemin »app.get('/clients/:id', (req, res) => { res.json({ id: req.params.id });});
app.get('/clients/:clientId/commandes/:commandeId', (req, res) => { const { clientId, commandeId } = req.params; res.json({ clientId, commandeId });});Les valeurs de req.params sont toujours des chaînes : convertir (Number(req.params.id)) et valider.
Syntaxe des chemins (Express 5)
Section intitulée « Syntaxe des chemins (Express 5) »| Besoin | Express 5 |
|---|---|
| Paramètre | /clients/:id |
| Paramètre optionnel | /clients{/:id} |
| Joker nommé | /fichiers/*chemin (valeur dans req.params.chemin, un tableau de segments) |
| Joker (toute URL) | /*splat |
| Paramètre avec contrainte | À valider dans le gestionnaire (les expressions régulières dans le chemin ne sont plus prises en charge) |
app.get('/archives{/:annee}', (req, res) => { res.json({ annee: req.params.annee ?? 'toutes' });});Chaîne de requête
Section intitulée « Chaîne de requête »// GET /recherche?q=alice&page=2&tri=nomapp.get('/recherche', (req, res) => { const { q = '', page = '1', tri = 'id' } = req.query; res.json({ q, page: Number(page), tri });});Valider les valeurs : un paramètre répété (?tri=a&tri=b) devient un tableau.
Corps de requête
Section intitulée « Corps de requête »app.use(express.json()); // application/jsonapp.use(express.urlencoded({ extended: false })); // formulaires HTML
app.post('/clients', (req, res) => { const { nom, email } = req.body ?? {}; if (!nom || !email) { return res.status(400).json({ erreur: 'nom et email obligatoires' }); } res.status(201).json({ id: 1, nom, email });});curl -X POST http://127.0.0.1:3000/clients \ -H 'Content-Type: application/json' \ -d '{"nom":"Alice","email":"alice@exemple.com"}'Express 5 : sans express.json(), req.body est undefined.
Réponses
Section intitulée « Réponses »| Méthode | Usage |
|---|---|
res.send(corps) |
Texte, HTML, tampon |
res.json(objet) |
JSON |
res.status(404).json(...) |
Fixer le code de statut |
res.sendStatus(204) |
Code seul avec son libellé |
res.redirect(301, '/nouveau') |
Redirection |
res.sendFile(chemin) |
Envoyer un fichier |
res.set('Cache-Control', 'no-store') |
En-tête de réponse |
res.cookie('nom', 'valeur', { httpOnly: true }) |
Cookie |
res.end() |
Terminer sans corps |
Codes courants : 200 OK, 201 créé, 204 sans contenu, 400 requête invalide, 401 non authentifié, 403 interdit, 404 introuvable, 409 conflit, 422 entité non traitable, 500 erreur serveur.
Routeurs modulaires
Section intitulée « Routeurs modulaires »src/routes/clients.js :
import { Router } from 'express';
export const routeur = Router();
routeur.get('/', (req, res) => res.json([{ id: 1, nom: 'Alice' }]));
routeur.get('/:id', (req, res) => { const id = Number(req.params.id); if (!Number.isInteger(id)) return res.status(400).json({ erreur: 'id invalide' }); res.json({ id, nom: 'Alice' });});
routeur.post('/', (req, res) => res.status(201).json({ id: 2, ...req.body }));src/app.js :
import express from 'express';import { routeur as clients } from './routes/clients.js';
export const app = express();app.use(express.json());app.use('/api/clients', clients);Un routeur regroupe les routes d’une ressource, monté sous un préfixe.
Regrouper les méthodes d’un même chemin
Section intitulée « Regrouper les méthodes d’un même chemin »routeur .route('/:id') .get((req, res) => res.json({ id: req.params.id })) .put((req, res) => res.json({ modifie: req.params.id })) .delete((req, res) => res.sendStatus(204));Ordre des routes
Section intitulée « Ordre des routes »Express évalue les routes dans l’ordre de déclaration : la première qui répond gagne.
app.get('/clients/nouveau', (req, res) => res.send('formulaire')); // d'abord le chemin précisapp.get('/clients/:id', (req, res) => res.send('fiche')); // puis le chemin génériqueapp.use((req, res) => res.status(404).json({ erreur: 'introuvable' })); // en dernier : 404Paramètres réutilisables
Section intitulée « Paramètres réutilisables »routeur.param('id', (req, res, next, id) => { if (!/^\d+$/.test(id)) return res.status(400).json({ erreur: 'id invalide' }); req.clientId = Number(id); next();});Tester une route
Section intitulée « Tester une route »curl -i http://127.0.0.1:3000/api/clientscurl -i -X DELETE http://127.0.0.1:3000/api/clients/1curl -s http://127.0.0.1:3000/api/clients | python3 -m json.toolDépannage
Section intitulée « Dépannage »| Symptôme | Piste |
|---|---|
Cannot GET /… |
Route absente, mauvaise méthode, mauvais préfixe de montage |
req.body est undefined |
express.json() manquant ou déclaré après la route |
| La route générique « avale » la route précise | Inverser l’ordre de déclaration |
TypeError: Missing parameter name |
Joker non nommé : /*splat |
| Paramètre toujours une chaîne | Normal : convertir avec Number() |
Cannot set headers after they are sent |
Deux réponses pour une requête : return res... |
Ubuntu 24.04 et 26.04 : différences à connaître
Section intitulée « Ubuntu 24.04 et 26.04 : différences à connaître »Aucune : Express 5 et Node.js se comportent de la même manière sur les deux versions.
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Routage
- Suite : Middlewares