Qu'est-ce que l'Idempotence ? Méthodes HTTP, Clés API, Exemples
Idempotence : appeler une opération N fois a le même effet qu'une fois — critique pour les retries sûrs. GET/PUT/DELETE sont idempotents.
Qu'est-ce que l'idempotence ?
L'idempotence est une propriété d'une opération où l'exécuter plusieurs fois produit le même résultat que l'exécuter une seule fois. En notation mathématique : f(x) = f(f(x)) = f(f(f(x))). Dans les contextes d'APIs et systèmes distribués, une opération idempotente peut être réessayée en toute sécurité sans causer d'effets secondaires non intentionnels — critique quand les réseaux sont peu fiables et que vous ne savez pas si votre requête précédente a réussi.
L'exemple classique est un bouton d'ascenseur : le presser une fois ou dix fois produit le même résultat (l'ascenseur arrive une fois). Comparez avec débiter une carte de crédit : presser "payer" dix fois sans idempotence produit dix débits. La conception idempotente rend les systèmes sûrs à réessayer.
Idempotence dans les APIs HTTP/REST
La spécification HTTP (RFC 7231) définit quelles méthodes sont idempotentes :
| Méthode HTTP | Idempotente ? | Usage typique |
|---|---|---|
| GET | Oui | Lire une ressource — appelé N fois retourne les mêmes données, pas de changement d'état |
| HEAD | Oui | Comme GET mais headers seulement |
| PUT | Oui | Remplacer une ressource — appelé N fois laisse la ressource dans le même état final |
| DELETE | Oui | Retirer une ressource — N fois : le premier la retire, les suivants sont no-ops |
| OPTIONS | Oui | Découvrir les méthodes permises |
| TRACE | Oui | Loopback diagnostique |
| POST | Non | Créer une ressource — appelé N fois crée typiquement N ressources |
| PATCH | Non (par défaut) | Mise à jour partielle — dépend de la sémantique |
Notez qu'idempotent ne signifie PAS "retourner la même réponse". DELETE retourne 204 la première fois et 404 aux appels suivants — réponses différentes, mais l'état serveur est identique. La propriété concerne l'état final, pas l'équivalence de réponse.
Exemples : idempotent vs non-idempotent
Opérations idempotentes
PUT /users/123 {"name": "Alice"}— fixe le nom de l'utilisateur à Alice. L'appeler 10 fois laisse le nom Alice.DELETE /sessions/abc— retire session abc.GET /products/42— lit produit 42.PUT /flags/feature-x {"enabled": true}— toggle de feature flag par valeur absolue.
Opérations non-idempotentes
POST /orders {...}— crée une nouvelle commande. 10 fois crée 10 commandes.POST /charges {...}— débite une carte. 10 fois débite 10 fois.PATCH /counters/x {"increment": 1}— incrémente de 1 à chaque appel.POST /emails {"to": "..."}— envoie un email. 10 appels = 10 emails.
Pourquoi l'idempotence compte
Dans un monde single-machine transactionnel, vous n'appelleriez jamais la même opération deux fois. Mais les systèmes modernes sont distribués — et ça change tout :
- Pannes réseau. Votre client envoie une requête, n'obtient pas de réponse. A-t-elle réussi ? Vous ne savez pas. Idempotente → réessayez en toute sécurité.
- Timeouts. Même problème. Le serveur peut avoir traité la requête après que le client a abandonné.
- Retries distribués. Service meshes, load balancers et SDKs auto-réessayent. Sûr seulement si upstream est idempotent.
- Architectures basées files. Les messages peuvent être livrés plus d'une fois (at-least-once). Les consumers doivent gérer les doublons idempotemment.
- Comportement utilisateur. Les utilisateurs double-cliquent les boutons submit, rafraîchissent les pages en cours de requête.
Clés d'idempotence
Pour les opérations naturellement non-idempotentes comme créer une commande ou débiter une carte, le pattern standard est la clé d'idempotence : un identifiant unique généré par le client (typiquement UUID) envoyé avec chaque requête. Le serveur enregistre le résultat indexé par cet ID et retourne le même résultat pour toute requête subséquente avec la même clé.
POST /charges
Idempotency-Key: 8e0a4e6b-1b8e-4e3a-b9f7-5e1d3f9c4b8a
{
"amount": 5000,
"currency": "USD"
}Le premier appel traite le débit et stocke le résultat. Les appels subséquents avec la même clé retournent le résultat stocké sans re-traitement. La clé expire typiquement après une fenêtre (ex. 24 heures).
Implémenter les clés d'idempotence côté serveur
- Recevoir la requête avec clé d'idempotence.
- Vérifier le key store (Redis, table DB) pour entrée existante.
- Si trouvée : retourner la réponse stockée (pas de side effects).
- Si pas trouvée : acquérir un lock sur la clé, traiter la requête, stocker la réponse, libérer le lock.
- Gérer les requêtes en vol : si un doublon arrive pendant que le premier est traité, attendre ou retourner 409 Conflict.
- Expirer les clés après la fenêtre convenue.
Exemples du monde réel
- Stripe. L'implémentation de référence. Chaque endpoint API qui change l'état accepte un header
Idempotency-Key. - AWS SDK. Beaucoup d'APIs AWS utilisent les paramètres ClientToken (clés d'idempotence) — EC2 RunInstances, RDS CreateDBInstance.
- PayPal, Square, Adyen. Tous les processeurs de paiement utilisent des clés d'idempotence.
- HTTP/2 + clients retry-aware. Les clients HTTP modernes auto-réessayent les méthodes idempotentes lors d'échecs de connexion.
Pièges courants
- Traiter PATCH comme toujours idempotent. Dépend de la sémantique.
- Side effects au-delà de la base de données. Si votre endpoint "idempotent" envoie un email, l'appeler deux fois envoie deux emails.
- Clés d'idempotence sans expiry. Stocker chaque clé pour toujours cause une croissance illimitée. Définissez des TTLs.
- Race conditions sur retries concurrents. Utilisez des locks ou contraintes DB.
- Confondre idempotence et safety. Safe = pas de side effects (GET). Idempotent = N appels = effet de 1 appel. PUT/DELETE sont idempotents mais pas safe.
Idempotence en load testing
- Les endpoints POST accumulent l'état. Un load test 1000-VU contre POST /orders crée 1000 × durée × rps commandes. Cleanup après.
- Réutiliser une clé d'idempotence cache la réponse. Si votre script réutilise la même clé entre VUs, tous les VUs obtiennent la réponse cachée.
- Générez des clés d'idempotence uniques par VU/itération.
- Testez le mécanisme d'idempotence lui-même.
FAQ : Idempotence
GET est-il toujours idempotent ?
Selon la spec HTTP, oui — GET ne devrait jamais modifier l'état. En pratique, certaines APIs détournent GET pour des changements d'état.
PATCH est-il idempotent ?
Dépend de l'opération. PATCH {set: x} est idempotent. PATCH {increment: 1} ne l'est pas.
Quelle est la différence entre idempotence et safety ?
Safe signifie pas d'effets secondaires observables (GET, HEAD, OPTIONS). Idempotent signifie N appels = état final de 1 appel. PUT et DELETE sont idempotents mais pas safe.
Comment rendre POST idempotent ?
Utiliser une clé d'idempotence — un ID unique généré par le client (UUID) envoyé avec chaque requête.
Quel est un bon TTL de clé d'idempotence ?
Stripe utilise 24 heures. Pour APIs high-throughput, 1 heure peut suffire. Pour APIs de paiement low-throughput, 7-30 jours donnent plus de tolérance de retry.
L'idempotence s'applique-t-elle à gRPC et GraphQL ?
Oui. Les définitions de méthode gRPC peuvent spécifier le niveau d'idempotence. Les opérations GraphQL Query sont idempotentes par convention ; les Mutations nécessitent une conception explicite d'idempotence.
Essayez LoadFocus pour tester l'idempotence at scale
Si vous concevez un mécanisme d'idempotence et voulez le vérifier sous charge (retries concurrents, race conditions, expiry de clés), LoadFocus exécute des scripts JMeter et k6 depuis 25+ régions cloud avec jusqu'à 12 500 VUs. Inscrivez-vous sur loadfocus.com/signup — pas de carte de crédit — et lancez votre premier stress test d'idempotence en moins de 5 minutes.
Outils LoadFocus connexes
Mettez ce concept en pratique avec LoadFocus — la plateforme même qui propulse tout ce que vous venez de lire.