HTTP et idempotence : quand peut-on réessayer une requête ?
Une réponse perdue ne signifie pas que l’opération a échoué. Méthodes HTTP, clés d’idempotence et suivi du résultat aident à réessayer sans créer de doublon.
Article
Une API peut utiliser les ressources et les méthodes HTTP sans proposer d’hypermédia. Ce choix influe sur la découverte des actions et l’évolution des clients.
Votre API expose des commandes et respecte les méthodes HTTP, mais le client doit connaître l'adresse du paiement dans sa documentation. Une réponse hypermédia pourrait lui fournir cette action directement. La différence porte sur la manière dont le client découvre le parcours et s'adapte à ses évolutions. Elle aide à choisir un contrat, sans réduire la qualité d'une API à son étiquette.
Le modèle de Richardson distingue quatre manières d'utiliser les mécanismes du Web. Présenté par Leonard Richardson en 2008 et popularisé par Martin Fowler en 2010, il sert à expliquer ces mécanismes. Il ne constitue pas une note globale de qualité pour une API.
| Niveau | Le geste | Ce qui manque encore |
|---|---|---|
| 0, le tunnel | une seule adresse, une seule méthode, tout y passe (SOAP, RPC) | tout : HTTP ne sert que d'enveloppe |
| 1, les ressources | une URL par chose : /commandes/42 | les actions s'appellent encore sur ces URL |
| 2, verbes et statuts | les méthodes HTTP et les codes de statut, employés selon leur sens | l'hypermédia, et c'est là que beaucoup s'arrêtent : Richardson le notait déjà en 2008, « a lot of people settle for level two » |
| 3, contrôles hypermédia | les réponses portent des liens et des formulaires (HATEOAS) | le reste des règles de Fielding : décrire des types de média plutôt que des routes, ne pas figer les noms de ressources. Le niveau 3 est la condition d'entrée, pas le certificat |
Une API couramment appelée « REST » peut proposer des ressources et des méthodes HTTP sans décrire les actions disponibles dans ses réponses. Elle relève alors du niveau 2 de ce modèle. Les autres contraintes de REST restent à examiner séparément.
C'est la règle que REST nomme HATEOAS. Il l'a écrit en 2008 dans un billet resté célèbre : si le moteur de l'état applicatif n'est pas piloté par l'hypertexte, ce n'est pas du REST, et ce ne peut pas être une API REST.
Une API sans contrôles hypermédia ne satisfait pas entièrement le style REST de Fielding. Cela ne suffit pas à la qualifier de RPC ni à conclure qu'elle est mal conçue. Elle peut respecter les ressources et la sémantique HTTP, tout en choisissant un contrat connu du client à l'avance.
Fowler distingue également le modèle de Richardson de la définition complète de REST. Le niveau 3 indique la présence de contrôles hypermédia ; il ne vérifie pas à lui seul les contraintes de cache, d'absence d'état ou les autres aspects du style.
Si les adresses et les transitions sont fixées dans le code client, une modification incompatible peut imposer sa mise à jour. Le contrat existe alors en dehors des réponses, dans une documentation ou un schéma partagé. C'est une forme de couplage hors bande.
Ce contrat a son outil roi, OpenAPI, l'ancien Swagger : un fichier décrit les routes, les paramètres et la forme des réponses, d'où sortent clients et documentation.
OpenAPI facilite la documentation, la validation et la génération de clients. Il peut aussi documenter une API hypermédia. Le point à vérifier est ce que le client fige dans son code et ce qu'il découvre réellement au cours des échanges.
La différence se voit dans une réponse. Au niveau 2, une commande renvoie ses données brutes, et le client doit savoir par ailleurs à quelle URL la payer ou l'annuler :
{ "reference": "C-42", "statut": "en attente de paiement" }
Au niveau 3, la même réponse porte ses transitions, et le client n'a qu'à suivre :
{
"reference": "C-42",
"statut": "en attente de paiement",
"_liens": {
"payer": { "method": "POST", "href": "/commandes/C-42/paiement" },
"annuler": { "method": "DELETE", "href": "/commandes/C-42" }
}
}
Dans le second exemple, le client reçoit la destination des actions. Il doit encore comprendre le sens de « payer » et de « annuler », ainsi que le format employé pour les décrire. La dépendance aux chemins diminue ; le contrat métier reste partagé.
Une version dans l'URL, telle que /v1/, rend explicite un contrat qui peut changer. Elle ne condamne pas toutes les évolutions : des ajouts compatibles restent possibles. Une rupture exige en revanche une stratégie de migration pour les clients concernés.
Fielding s'en est expliqué en 2014, dans un entretien à InfoQ : il n'y a pas d'évolutivité si les contrôles d'un client « sont cuits dans sa conception au moment du déploiement ». Ils doivent s'apprendre à la volée, ce que l'hypermédia permet.
Une nouvelle version demande de décider combien de temps conserver l'ancienne, comment informer ses utilisateurs et comment vérifier leur migration. L'hypermédia réduit certaines dépendances, mais ne rend pas compatible un changement de sens des données ou des actions.
Fielding propose de considérer une rupture profonde comme un nouveau système. Cette position met en évidence le coût réel de la transition. Pour une API existante, le choix doit aussi tenir compte des clients que vous ne pouvez pas mettre à jour vous-même.
Si une même équipe livre client et serveur ensemble, un contrat OpenAPI peut être parfaitement adapté. La coordination des versions est plus facile que pour une API publique utilisée par des clients inconnus. Je commencerais par ce besoin d'évolution avant d'ajouter des contrôles hypermédia partout.
GraphQL et gRPC répondent autrement au couplage : ils misent sur un schéma fortement typé, partagé par les deux bouts, dont le code se génère de chaque côté. C'est l'inverse du client générique, et un choix cohérent quand l'évolutivité ouverte n'est pas le but.
| Votre situation | Le choix adapté |
|---|---|
| Client et serveur d'une même équipe, livrés ensemble | niveau 2 et OpenAPI peuvent suffire ; évaluer le besoin de découverte dynamique |
| Plusieurs consommateurs internes, qui évoluent en décalé | un niveau 2 solide, avec de l'hypermédia sur les seules ressources qui changent souvent |
| API publique, clients tiers non contrôlés, longue durée de vie | niveau 3 (hypermédia), ou un versionnage assumé et documenté |
| Client qui reçoit trop ou trop peu de données (mobile, écrans variés) | GraphQL, pour laisser le client composer sa requête |
| Appels entre services internes, latence et typage critiques | gRPC, contrat typé et binaire |
| API destinée à un agent | niveau 3, l'hypermédia |
Une API claire, documentée et compatible avec ses consommateurs peut remplir son rôle sans viser toutes les contraintes de REST. L'essentiel est d'expliciter ce que le client doit connaître et les changements que le fournisseur s'engage à préserver.
L'hypermédia devient intéressant lorsque les parcours et les destinations évoluent pour plusieurs clients indépendants. Il demande toutefois des consommateurs capables de suivre ces contrôles. L'article sur les interfaces rendues par le serveur présente une application concrète de cette idée.
Explorer
Choisis dans l’index d’après les étiquettes de cet article — les plus proches d’abord, hors de sa série. Rien n’est écrit à la main : un article publié demain avec les mêmes étiquettes y prendra place.
Une réponse perdue ne signifie pas que l’opération a échoué. Méthodes HTTP, clés d’idempotence et suivi du résultat aident à réessayer sans créer de doublon.
GET sert souvent les vues de lecture, tandis que les écritures demandent une décision métier. REST et CQRS se combinent sans imposer le même découpage.
Une dépendance ne répond plus : servir une copie, attendre ou refuser dépend de l’opération. Les réponses HTTP doivent rendre ce choix clair pour le client.
Laisser un commentaire
Votre commentaire sera relu avant d'être publié.