Structurer une API REST que l'on peut encore maintenir six mois plus tard
Les trois décisions d'architecture qui font la différence entre une API agréable à faire évoluer et un projet que l'on redoute d'ouvrir.
- Architecture
- API
- Bonnes pratiques
Sur mes premiers projets, je démarrais toujours de la même façon : un fichier routes.js, quelques fonctions, et la promesse de « ranger tout ça plus tard ». Six mois après, la moindre évolution demandait une demi-journée. Voici les trois décisions qui ont changé cela.
1. Séparer le transport de la logique métier
Le réflexe le plus rentable : une route HTTP ne doit rien savoir de votre métier. Elle lit la requête, appelle un service, et transforme le résultat en réponse.
// routes/orders.ts — ne fait que du transport
router.post("/orders", async (req, res) => {
const input = createOrderSchema.parse(req.body);
const order = await orderService.create(input);
res.status(201).json(toOrderResponse(order));
});
L'intérêt est immédiat : le jour où vous ajoutez une commande en ligne de commande, un traitement par lot ou une file de messages, la logique est déjà réutilisable telle quelle.
2. Valider aux frontières, pas partout
Une donnée qui entre dans le système est validée une seule fois, au point d'entrée. Passé cette frontière, elle est considérée comme fiable et correctement typée.
Cela évite le code défensif qui pollue chaque fonction :
// Inutile si la validation a déjà eu lieu à l'entrée
if (!order || !order.items || order.items.length === 0) { /* ... */ }
Concrètement, j'utilise un schéma par point d'entrée, et j'en déduis le type TypeScript. Une seule source de vérité pour la validation et le typage.
3. Traiter les erreurs comme une partie de l'API
Une erreur est une réponse comme une autre : elle mérite un format stable et documenté.
| Cas | Statut | Corps |
|---|---|---|
| Données invalides | 422 | { code, fields } |
| Ressource absente | 404 | { code } |
| Conflit métier | 409 | { code, message } |
Le point important est le champ code : un identifiant stable que le client peut tester, contrairement à un message destiné aux humains et susceptible d'être reformulé ou traduit.
Ce que j'en retiens
Ces trois règles ne coûtent presque rien à mettre en place au démarrage, et elles évitent la réécriture complète six mois plus tard. Si je ne devais en garder qu'une, ce serait la première : la séparation entre transport et métier, parce que c'est celle qui est la plus douloureuse à rattraper après coup.