TW3 — Technologies du Web 3

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.

VerbeIdempotentConséquence pratique
GET✅ OuiUn client peut réessayer sans risque après un timeout
PUT✅ OuiRemplacer une ressource plusieurs fois donne le même résultat
DELETE✅ OuiSupprimer deux fois la même ressource : elle reste supprimée
POST❌ NonRejouer un POST peut créer un doublon
PATCH⚠️ Non garantieDé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.params pour l'identité, req.query pour le filtrage.
  • Les routes fixes se déclarent avant les routes dynamiques.
  • Un Router par ressource garde app.js lisible.

Express

Terminez le quiz du chapitre pour le marquer comme complété.

Tableau de bord

On this page