Skip to content

API Express et validation fr FR

rocambille edited this page Jun 4, 2026 · 2 revisions

Résumé : Cette page détaille des concepts avancés du routage Express dans StartER, notamment l'usage de factories pour simplifier la conversion des paramètres d'URL et la validation des données avec Zod.

Manipulation et sécurité des requêtes

Le backend doit garantir que les données reçues via les requêtes HTTP sont conformes aux attentes avant de les traiter. Pour réduire le code répétitif (boilerplate), StartER fournit deux utilitaires dans src/express/helpers : createParamConverter et createValidator.

Convertir des paramètres (createParamConverter)

Les "param converters" transforment un paramètre d'URL (comme :itemId) en un objet métier complet (une entité) chargé depuis la base de données.

Le fichier itemParamConverter.ts utilise la factory createParamConverter :

import { createParamConverter } from "../../helpers/paramConverter";
import itemRepository from "./itemRepository";

export default createParamConverter(itemRepository, "item");

Cette simple ligne de code :

  1. Déclare que nous voulons convertir un paramètre en utilisant itemRepository.
  2. Indique que l'entité trouvée sera injectée dans req.item.
  3. Gère automatiquement les erreurs : si l'ID n'existe pas, il renvoie un 404 Not Found (ou 204 No Content pour une requête DELETE).

Typage TypeScript

Pour que req.item soit reconnu par TypeScript, nous étendons l'interface Request :

declare global {
  namespace Express {
    interface Request {
      item: Item;
    }
  }
}

Valider les entrées (createValidator)

Avant de modifier des données, StartER utilise Zod via la factory createValidator pour valider et assainir req.body.

Exemple dans itemValidator.ts :

import { z } from "zod";
import { createValidator } from "../../helpers/validation";

const itemDTOSchema = z.object({
  title: z.string().max(255),
  user_id: z.number(),
});

export default createValidator(itemDTOSchema, (req) => ({
  ...req.body,
  // Injection de données serveur de confiance (ID de l'utilisateur connecté)
  user_id: req.me.id,
}));

Pourquoi utiliser cette factory ?

  • Assainissement : req.body est remplacé par le résultat de schema.parse(). Seuls les champs définis dans le schéma sont conservés.
  • Formatage : Zod peut transformer les types (ex : string en number).
  • Fail fast : si les données sont invalides, le serveur renvoie immédiatement un 400 Bad Request avec le détail des erreurs Zod.
  • Données de confiance : le second argument optionnel permet de "fusionner" les données du client avec des données serveur (comme req.me.id).

Utilisation dans les routes

L'association de ces outils permet de garder les routes et les actions extrêmement propres :

// src/express/modules/item/itemRoutes.ts
itemRoutes.param("itemId", itemParamConverter.convert);

itemRoutes.post("/api/items", itemValidator.validate, itemActions.add);
itemRoutes.put("/api/items/:itemId", itemValidator.validate, itemActions.edit);

Grâce à cette structure, l'action edit peut supposer que req.item existe et que req.body est parfaitement valide et typé :

// src/express/modules/item/itemActions.ts
const edit: RequestHandler = (req, res) => {
  const item = { ...req.body, id: req.item.id };

  itemRepository.update(item);

  res.sendStatus(204);
};

Bonnes pratiques

  • Validez systématiquement : ne faites jamais confiance aux données envoyées par le client.
  • Injection serveur : préférez injecter l'ID de l'utilisateur (req.me.id) dans le validateur plutôt que de le recevoir du client.
  • Idempotence : le convertisseur renvoie 204 sur un DELETE si la ressource n'existe plus, assurant qu'une suppression répétée ne provoque pas d'erreur 404 inutile.

Voir aussi

Clone this wiki locally