Concevoir des API REST idempotentes et versionnées

Backend2026-09-17TryQuickToolBox

Vous déployez une nouvelle fonctionnalité, et soudain votre API reçoit des requêtes POST en double de la part de clients qui réessaient après un timeout. Votre base de données contient maintenant deux commandes identiques. Ou vous déployez un changement incompatible, et les applications mobiles plantent car elles attendaient l'ancien format de réponse. Ce sont deux des problèmes les plus courants et douloureux dans la conception d'API : les opérations non idempotentes et les changements incompatibles. Ce guide vous montre comment résoudre les deux avec des patterns pratiques pour l'idempotence et le versioning dans les API REST.

Pourquoi l'idempotence est importante dans les API REST

L'idempotence signifie que faire la même requête plusieurs fois a le même effet que la faire une fois. Les méthodes HTTP ont des sémantiques d'idempotence définies : GET, HEAD, PUT, DELETE et OPTIONS sont idempotentes, tandis que POST et PATCH ne le sont pas. Mais les API du monde réel doivent souvent accepter POST pour des opérations comme la création de ressources ou le traitement de paiements. Les pannes réseau, les timeouts clients et la logique de retry peuvent causer des doublons. Sans idempotence, vous risquez des doubles débits, des enregistrements en double ou un état incohérent.

Techniques pour des API REST idempotentes

1. Utilisez des clés d'idempotence pour les requêtes POST

L'approche la plus courante consiste à laisser les clients envoyer une clé unique (par exemple, un UUID) dans un en-tête Idempotency-Key. Le serveur stocke la clé et le résultat de l'opération. Si la même clé est reçue à nouveau, le serveur renvoie le résultat stocké au lieu de réexécuter l'opération.

POST /payments
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
Content-Type: application/json

{
  "amount": 1000,
  "currency": "USD"
}

Étapes de mise en œuvre :

  1. Le client génère une clé unique (UUID v4) pour chaque opération logique.
  2. Le serveur vérifie si la clé existe dans un stockage persistant (par exemple, Redis ou base de données).
  3. Si non, traite la requête et stocke la clé avec le statut et le corps de la réponse.
  4. Si oui, renvoie la réponse stockée sans retraiter.

Définissez une expiration raisonnable (par exemple, 24 heures) pour éviter une croissance illimitée du stockage.

2. Tirez parti des requêtes conditionnelles

Pour les mises à jour, utilisez les en-têtes ETag et If-Match pour éviter les mises à jour perdues. Le serveur renvoie un ETag représentant l'état actuel. Le client le renvoie avec If-Match ; si la ressource a changé, le serveur renvoie 412 Precondition Failed. Cela rend les requêtes PUT sûres contre les conditions de course.

PUT /articles/123
If-Match: "abc123"
Content-Type: application/json

{"title": "Titre mis à jour"}

3. Concevez PUT pour une idempotence naturelle

Préférez PUT à POST lorsque le client peut déterminer l'URL de la ressource. Par exemple, PUT /users/{userId} est naturellement idempotent car les appels répétés écrasent la même ressource. Utilisez POST uniquement lorsque le serveur attribue l'ID.

4. Gérez la détection des doublons avec des contraintes uniques

Combinez les clés d'idempotence avec des contraintes uniques de base de données sur les clés métier (par exemple, numéro de commande). Si un doublon passe, la base de données le rejette, et vous pouvez renvoyer un 409 Conflict avec un message clair.

Stratégies de versioning pour les API REST

Les API évoluent. De nouveaux champs, un comportement modifié ou des points de terminaison supprimés peuvent casser les clients existants. Le versioning vous permet d'introduire des changements sans les perturber. Il existe plusieurs stratégies courantes :

Stratégie Exemple Avantages Inconvénients
Chemin d'URI /v1/users Explicite, facile à router, compatible avec le cache Les URLs changent, peut encombrer
Paramètre de requête /users?version=1 Simple, optionnel Facile à omettre, pas RESTful
En-tête personnalisé Accept-Version: v1 Garde les URLs propres Plus difficile à tester dans le navigateur
Type de média Accept: application/vnd.api.v1+json Négociation de contenu, REST pur Complexe, moins courant

Pour la plupart des équipes, le versioning par chemin d'URI est le choix le plus pragmatique. Il est visible, facile à documenter et fonctionne bien avec les passerelles API et les CDN.

Comment versionner sans casser les clients

  1. Commencez avec v1 dans le chemin dès le premier jour. Ajouter le versioning plus tard est plus difficile.
  2. Modifications additives uniquement dans une version : nouveaux champs optionnels, nouveaux points de terminaison. Ne supprimez jamais et ne renommez jamais les champs.
  3. Dépréciez avec élégance : annoncez la fin de vie, fournissez des guides de migration et surveillez l'utilisation des anciennes versions.
  4. Utilisez les en-têtes Sunset : Sunset: Sat, 31 Dec 2025 23:59:59 GMT pour informer les clients.
  5. Maintenez au maximum deux versions actives pour limiter la charge de maintenance.

Mise en pratique : un exemple concret

Considérez une API de paiement. Vous voulez créer un paiement de manière idempotente et versionner le point de terminaison.

POST /v1/payments
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
Content-Type: application/json

{
  "amount": 1000,
  "currency": "USD"
}

Logique serveur :

Pour les mises à jour, utilisez PUT avec ETag :

PUT /v1/payments/123
If-Match: "xyz789"
Content-Type: application/json

{"amount": 1500}

Si l'ETag ne correspond pas, renvoyez 412. Cela empêche d'écraser des modifications concurrentes.

Pièges courants et comment les éviter

FAQ

Qu'est-ce qu'une API REST idempotente ?

Une API REST idempotente garantit que faire la même requête plusieurs fois produit le même résultat que de la faire une fois. C'est crucial pour gérer les retries en toute sécurité, surtout pour les méthodes non idempotentes comme POST.

Quelles méthodes HTTP sont idempotentes ?

GET, HEAD, PUT, DELETE, OPTIONS et TRACE sont idempotentes. POST et PATCH ne le sont pas par défaut, mais vous pouvez les rendre idempotentes en utilisant des techniques comme les clés d'idempotence.

Quelle est la meilleure façon de versionner une API REST ?

Le versioning par chemin d'URI (par exemple, /v1/users) est l'approche la plus courante et pratique. Il est explicite, facile à router et fonctionne bien avec la mise en cache et les passerelles API. D'autres options incluent les paramètres de requête, les en-têtes personnalisés et les types de média, mais elles ont des compromis.

Prêt à tester les réponses JSON de votre API ? Utilisez notre JSON Formatter pour valider et embellir les payloads rapidement.