Aller au contenu

Express : routes

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éthodes
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.

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' });
});
// GET /recherche?q=alice&page=2&tri=nom
app.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.

app.use(express.json()); // application/json
app.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 });
});
Fenêtre de terminal
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.

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.

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.

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));

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écis
app.get('/clients/:id', (req, res) => res.send('fiche')); // puis le chemin générique
app.use((req, res) => res.status(404).json({ erreur: 'introuvable' })); // en dernier : 404
routeur.param('id', (req, res, next, id) => {
if (!/^\d+$/.test(id)) return res.status(400).json({ erreur: 'id invalide' });
req.clientId = Number(id);
next();
});
Fenêtre de terminal
curl -i http://127.0.0.1:3000/api/clients
curl -i -X DELETE http://127.0.0.1:3000/api/clients/1
curl -s http://127.0.0.1:3000/api/clients | python3 -m json.tool
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.