Routing
Méthodes HTTP, paramètres de route, query string et organisation des routes avec express.Router.
Une route associe un verbe HTTP et un chemin à une fonction de traitement. C'est le cœur de toute API REST.
🛤️ Les verbes de base
app.get("/articles", listerArticles); // lire une collection
app.get("/articles/:id", lireArticle); // lire un élément
app.post("/articles", creerArticle); // créer
app.put("/articles/:id", remplacerArticle);// remplacer entièrement
app.patch("/articles/:id", modifierArticle);// modifier partiellement
app.delete("/articles/:id", supprimerArticle);Convention REST : le chemin décrit une ressource (un nom, au pluriel), le verbe décrit l'action. On n'écrit donc jamais /getArticles ni /deleteArticle/3.
🔖 Paramètres de route
Un segment préfixé par : devient une variable disponible dans req.params.
app.get("/articles/:id", (req, res) => {
const { id } = req.params; // toujours une chaîne de caractères
res.json({ id: Number(id) });
});Plusieurs paramètres sont possibles :
app.get("/cours/:module/:chapitre", (req, res) => {
const { module, chapitre } = req.params;
res.json({ module, chapitre });
});Les valeurs de req.params sont toujours des chaînes. req.params.id === 1 sera faux même pour /articles/1 : convertissez avec Number() avant toute comparaison ou requête en base.
❓ Query string
Ce qui suit le ? sert à filtrer, trier, paginer. Ces paramètres sont optionnels et se lisent dans req.query.
// GET /articles?tag=node&page=2&limit=10
app.get("/articles", (req, res) => {
const page = Number(req.query.page) || 1;
const limit = Number(req.query.limit) || 20;
const tag = req.query.tag ?? null;
res.json({ page, limit, tag });
});Règle simple : ce qui identifie une ressource va dans le chemin, ce qui la filtre va dans la query string.
⚠️ L'ordre des routes compte
app.get("/articles/nouveau", afficherFormulaire); // ✅ avant la route dynamique
app.get("/articles/:id", lireArticle);Inversées, /articles/nouveau serait capturée par :id avec la valeur "nouveau".
🧱 express.Router
Quand les routes s'accumulent, on les regroupe par ressource dans un routeur monté sur un préfixe.
Déclarer le routeur
// routes/articles.routes.js
import { Router } from "express";
const router = Router();
router.get("/", (req, res) => res.json([]));
router.get("/:id", (req, res) => res.json({ id: req.params.id }));
router.post("/", (req, res) => res.status(201).json(req.body));
export default router;Le monter sur l'application
// app.js
import articlesRouter from "./routes/articles.routes.js";
app.use("/api/articles", articlesRouter);Les chemins du routeur sont relatifs au préfixe : router.get("/:id") répond en réalité à /api/articles/:id. Changer le préfixe ne demande alors qu'une seule modification.
🔗 Chaînage avec route()
router
.route("/:id")
.get(lireArticle)
.put(remplacerArticle)
.delete(supprimerArticle);Pratique quand plusieurs verbes partagent le même chemin.
🔁 Idempotence et verbes HTTP
Une opération est idempotente quand la répéter donne le même état final que l'exécuter une seule fois.
| Verbe | Idempotent | Conséquence pratique |
|---|---|---|
GET | ✅ Oui | Un client peut réessayer sans risque après un timeout |
PUT | ✅ Oui | Remplacer une ressource plusieurs fois donne le même résultat |
DELETE | ✅ Oui | Supprimer deux fois la même ressource : elle reste supprimée |
POST | ❌ Non | Rejouer un POST peut créer un doublon |
PATCH | ⚠️ Non garantie | Dépend de l'implémentation |
Conséquence pratique : un client peut réessayer sans risque un GET, un PUT ou un DELETE après un timeout, mais rejouer un POST peut créer un doublon. Pour sécuriser un POST, utilisez une clé d'idempotence fournie par le client.
🏷️ Versioning d'API
Quand une API évolue, il faut pouvoir introduire des changements sans casser les clients existants. Le versioning permet de coexister plusieurs versions de la même API.
// Version 1 — routes historiques
app.use("/api/v1/articles", articlesRouterV1);
// Version 2 — nouvelles fonctionnalités
app.use("/api/v2/articles", articlesRouterV2);Le versioning par préfixe d'URL (/api/v1/, /api/v2/) est l'approche la plus simple et la plus visible. Alternative : l'en-tête Accept: application/vnd.monapi.v2+json.
✅ Points clés
- Le chemin nomme la ressource, le verbe exprime l'action.
req.paramspour l'identité,req.querypour le filtrage.- Les routes fixes se déclarent avant les routes dynamiques.
- Un
Routerpar ressource gardeapp.jslisible.
Express
Terminez le quiz du chapitre pour le marquer comme complété.