Idempotence HTTP : répéter une requête sans aggraver les dégâts
Comprendre ce que la spécification HTTP promet lorsqu’une requête est renvoyée, et pourquoi l’état final du serveur compte davantage que le code de réponse reçu.
Où en êtes-vous avec cette notion ?
Une indication personnelle, enregistrée uniquement dans ce navigateur.
À lire ensuite
Le format café
L’essentiel à comprendre, le temps d’un café.
Envie de creuser ? Un cours plus complet vous attend juste après, à déplier sans quitter cette page.
Ce que vous allez comprendre
Pourquoi rejouer une requête HTTP est parfois sans conséquence et parfois catastrophique, et ce que la spécification promet réellement à propos de GET, PUT, DELETE et POST.
Une définition qui parle de l’état final
Une méthode est idempotente si l’effet de plusieurs requêtes identiques sur l’état du serveur est le même que celui d’une seule requête.
Le mot important est état. On ne parle pas de la réponse renvoyée, mais de ce que le système contient une fois l’opération terminée.
Sûr n’est pas idempotent
Deux propriétés se ressemblent et se confondent souvent.
- Une méthode sûre (safe) n’est pas censée modifier l’état : elle lit.
GETetHEADsont sûres. - Une méthode idempotente peut modifier l’état, mais la répéter n’aggrave rien.
PUTetDELETEle sont.
Toute méthode sûre est donc aussi idempotente. L’inverse est faux : DELETE supprime bel et bien, il n’est pas sûr.
Le tour des méthodes
GET → sûre et idempotente (elle lit)
PUT → idempotente (elle définit un état)
DELETE → idempotente (l’absence reste l’absence)
POST → généralement non idempotente (elle crée)
Un PUT /api/users/42 portant ce corps :
{ "name": "Jean", "active": true }
laisse name = Jean et active = true, qu’il parte une fois ou dix fois. Un POST /api/orders, lui, crée généralement une commande de plus à chaque appel. C’est le double clic sur « Payer » qui débite deux fois.
La nuance qui surprend
Un premier DELETE /users/42 peut répondre 204 No Content, le second 404 Not Found. Les codes diffèrent, mais l’utilisateur 42 n’existe plus dans les deux cas. L’état final est identique : la méthode reste idempotente.
Une propriété attendue, pas une garantie
La spécification décrit ce qu’une méthode devrait faire. Elle ne vérifie pas votre code. Un PUT qui incrémente un compteur à chaque appel n’est pas idempotent, même s’il s’appelle PUT. L’idempotence est une promesse que votre implémentation doit tenir.
Pour rendre répétable une opération qui ne l’est pas par nature, on joint à la requête une clé d’idempotence, souvent dans un en-tête Idempotency-Key. Sa mise en œuvre côté serveur fait l’objet du cours « La clé d’idempotence ».
Fiche mémo
| Méthode | Sûre | Idempotente |
|---|---|---|
GET | oui | oui |
PUT | non | oui |
DELETE | non | oui |
POST | non | généralement non |
L’idée à emporter : l’idempotence se juge sur l’état final du serveur, jamais sur le code de réponse reçu.
Et si on allait plus loin ?
Le café vous a donné les repères. Prenez maintenant le temps de comprendre les mécanismes et de pratiquer, si vous le souhaitez.
Aller plus loinLire la sémantique HTTP pour décider si une requête peut être rejouéeDévelopper le coursReplier le cours
Ce que vous saurez faire
Classer une méthode HTTP comme sûre, idempotente ou ni l’une ni l’autre ; décider si un client peut renvoyer une requête après un échec réseau ; repérer une implémentation qui trahit la promesse de sa méthode.
1. Trois propriétés distinctes
La spécification HTTP décrit trois qualités indépendantes.
- Sûre : la requête est une demande de lecture. Elle ne devrait pas provoquer de modification observable.
- Idempotente : plusieurs requêtes identiques ont le même effet sur l’état du serveur qu’une seule.
- Cacheable : la réponse peut être conservée puis réutilisée.
GET cumule les trois. PUT et DELETE sont idempotents sans être sûrs. POST n’est en principe ni sûr ni idempotent, même si une réponse à un POST peut être mise en cache dans des conditions précises.
Référence : RFC 9110, sémantique HTTP.
2. Vérifier l’idempotence par l’état, pas par la réponse
Contexte d’exécution : un terminal avec curl, face à une API REST que vous administrez. Rien ne tourne sans ce serveur, et le domaine ci-dessous est illustratif.
curl -i -X DELETE https://api.exemple.test/users/42
curl -i -X DELETE https://api.exemple.test/users/42
Résultat attendu : la première commande affiche généralement 204 No Content, la seconde 404 Not Found.
Ces deux codes différents ne posent aucun problème. La question à poser est autre : « après ces deux appels, l’utilisateur 42 existe-t-il ? » La réponse est non, exactement comme après un seul appel. DELETE tient sa promesse.
Comparez avec un compteur de consultations :
curl -i -X PUT https://api.exemple.test/articles/7/vue
Si chaque appel incrémente le compteur, l’état final dépend du nombre d’appels. La méthode s’appelle PUT, mais l’opération n’est pas idempotente. L’étiquette ne fait pas la propriété.
Référence : documentation HTTP.
3. Pourquoi le client s’appuie sur cette promesse
Un échange peut se terminer dans l’ambiguïté.
Client
│ PUT /users/42
▼
Serveur
│
├── ressource mise à jour
│
└── réponse perdue en route
Le client voit une erreur réseau et ignore ce qui s’est réellement passé. Si la méthode est idempotente, il peut renvoyer la même requête sans analyse supplémentaire : au pire, il réécrit la même valeur.
C’est ce que font les bibliothèques HTTP qui rejouent automatiquement une requête. Elles le font pour GET, PUT et DELETE, rarement pour POST. Concevoir une API idempotente, c’est donc autoriser vos clients à rester simples.
Pièges et limites
- Confondre idempotent et sûr. Un
DELETErépété n’aggrave rien, mais le premier appel détruit une donnée. Une méthode idempotente peut être destructrice. - Croire que le code de réponse doit être identique.
204puis404sont parfaitement compatibles avec l’idempotence. Certains serveurs répondent204les deux fois : c’est un choix, pas une obligation. - Écrire un
PUTpartiel. Si votrePUTfusionne le corps reçu avec l’existant au lieu de définir la ressource entière, l’ordre des requêtes se met à compter.PATCH, de son côté, n’est pas idempotent en général. - Oublier les effets de bord externes. Un
PUTidempotent en base qui envoie un courriel à chaque appel produit dix courriels pour dix requêtes. L’état visible par le client ne résume pas tout. - Attendre une garantie de la spécification. Elle décrit une attente, pas un contrôle. Seuls vos tests vérifient que la promesse est tenue.
À vous de jouer
Une API expose ces trois opérations. Pour chacune, dites si elle est sûre, idempotente, ou aucune des deux, et justifiez par l’état final.
GET /api/factures/2024-08qui, à la première consultation, marque la facture comme lue.PUT /api/utilisateurs/42/preferencesqui remplace entièrement l’objet des préférences.POST /api/utilisateurs/42/relancesqui ajoute une relance à l’historique.
Correction commentée
1. Non sûre, et pourtant idempotente — le vrai problème est ailleurs. Un GET qui modifie l’état viole la sûreté attendue de la méthode. Sur l’état final, l’opération est bien idempotente : après le premier appel la facture est lue, et les suivants ne changent plus rien. Mais un cache, un préchargement du navigateur ou un robot d’indexation peuvent déclencher ce GET sans intention humaine. Le marquage doit passer par une requête explicite.
2. Idempotente, non sûre. Le corps décrit l’état voulu au complet. Dix envois du même corps laissent exactement les mêmes préférences qu’un seul envoi. Elle n’est pas sûre puisqu’elle écrit. Attention : si l’implémentation ne remplace que les champs fournis, elle redevient dépendante de l’ordre des requêtes et perd la propriété.
3. Ni l’une ni l’autre. Chaque appel ajoute une ligne : deux requêtes identiques produisent deux relances. C’est le comportement normal de POST. Pour autoriser une nouvelle tentative après un échec réseau, il faut une clé d’idempotence transmise par le client, sujet traité dans le cours consacré à sa mise en œuvre.
Vous pouvez aussi vous arrêter ici. L’approfondissement est facultatif.
Les repères Cours Café
Pour aller à la source
Documentation de référence. Vérification éditoriale encore à effectuer.
Gardez une trace de cette idée.
Favoris, notes et progression seront disponibles après connexion du stockage distant.