Concepts expliqués ~1 min de lecture

Éviter les doublons après un timeout API

Un timeout côté client ne dit pas si l’action a échoué. Il dit seulement que la réponse n’est pas revenue à temps.

Diagramme en deux colonnes. À gauche, sans clé d’idempotency: le client envoie POST /payments, le serveur crée payment #1, le client time out puis retry, le serveur crée payment #2, résultat doublon. À droite, avec Idempotency-Key: le client envoie POST /payments plus la clé, le serveur crée payment #1 et stocke le résultat, le client time out puis retry avec la même clé, le serveur renvoie le même résultat, pas de doublon.
Le schéma montre qu’après un timeout, un retry crée un doublon sans clé d’idempotency, mais rejoue le même résultat avec une clé d’idempotency.

Un timeout côté client ne prouve pas que l’opération a échoué. Il indique seulement que la réponse n’est pas arrivée dans le délai attendu. Entre-temps, le serveur a peut-être déjà exécuté l’action.

C’est pour cela qu’un retry n’est pas automatiquement sûr. Si le client renvoie une requête de création sans mécanisme d’idempotency, le serveur peut exécuter deux fois la même intention et produire des doublons.

La solution courante consiste à envoyer une clé d’idempotency, par exemple Idempotency-Key. Pour une même clé, le serveur traite la première requête, conserve le résultat, puis renvoie ce même résultat si la requête est rejouée. L’implémentation exacte dépend du système, mais l’objectif reste le même: reconnaître la même demande logique.

Exemple: un client envoie POST /payments avec Idempotency-Key: pay_9f3.... Si la réponse se perd après traitement, le client peut retry. Le serveur ne crée pas un second paiement; il renvoie le résultat déjà associé à cette clé.