REST DELETE est-il vraiment idempotent?

166

DELETE est censé être idempotent.

Si JE SUPPRIME http://example.com/account/123, cela supprimera le compte.

Si je le refais, est-ce que je m'attendrais à un 404, puisque le compte n'existe plus? Que faire si j'essaye de SUPPRIMER un compte qui n'a jamais existé?

Ben Noland
la source
11
En plus des réponses, je suggérerais de ne pas trop se concentrer sur la caractéristique idempotente en général: cela ne dit rien sur la commutativité et les demandes concurrentes. Par exemple, N + 1 de la même requête PUT "R1" devrait avoir le même effet, mais vous ne savez pas si un autre client a fait une requête PUT / DELETE "R2" différente entre les vôtres, donc alors que n R1 = R1 et m R2 = R2, quelque chose où vous obtenez des requêtes "R1" et "R2" entrelacées ne "sembleront" pas nécessairement idempotentes si vous ne prenez que la perspective d'un seul client.
Bruno

Réponses:

188

L'idempotence fait référence à l'état du système une fois la demande terminée


Dans tous les cas (à l'exception des problèmes d'erreur - voir ci-dessous), le compte n'existe plus.

D' ici

"Les méthodes peuvent également avoir la propriété" idempotence "en ce que ( mis à part les problèmes d'erreur ou d'expiration ), les effets secondaires de N> 0 requêtes identiques sont les mêmes que pour une seule requête. Les méthodes GET, HEAD, PUT et DELETE se partagent cette propriété. De plus, les méthodes OPTIONS et TRACE NE DEVRAIENT PAS avoir d'effets secondaires et sont donc intrinsèquement idempotentes. "


Le bit clé là est les effets secondaires de N> 0 demandes identiques est le même que pour une seule demande.

Vous auriez raison de vous attendre à ce que le code d'état soit différent, mais cela n'affecte pas le concept de base de l'idempotence - vous pouvez envoyer la demande plus d'une fois sans modifications supplémentaires de l'état du serveur.

Chris McCauley
la source
3
Effets secondaires! == état du serveur
wprl
2
@wprl Il y a un débat sur ce qu'est réellement cet "effet secondaire". Il peut s'agir de "l'état du serveur" ou d'une réponse envoyée au client. leedavis81.github.io/is-a-http-delete-requests-idempotent
Alireza
Voici un argument selon lequel 404 sur un deuxième SUPPRIMER peut en fait changer l'état du serveur: stackoverflow.com/a/45194747/317522
Paulo Merson
1
@PauloMerson Merci, personnellement, je ne pense pas qu'il soit important que le deuxième retour soit 404 ou 200, l'état du serveur n'a pas changé, donc je suis content de cela.
Chris McCauley
46

Idempotent concerne l'effet de la demande, pas le code de réponse que vous obtenez.

http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.2 dit:

Les méthodes peuvent également avoir la propriété d '«idempotence» en ce que (à part les problèmes d'erreur ou d'expiration), les effets secondaires de N> 0 demandes identiques sont les mêmes que pour une seule demande.

Bien que vous puissiez obtenir un code de réponse différent, l' effet de l'envoi de N + 1 demandes DELETE à la même ressource peut être considéré comme le même.

Bruno
la source
13

La distinction importante est que idempotent fait référence aux effets secondaires , et non à tous les effets ou réponses. Si vous faites une, DELETE http://example.com/account/123l'effet est que le compte 123 est maintenant supprimé du serveur. C'est le seul et unique effet, le seul et unique changement de l'état du serveur. Maintenant, disons que vous faites à nouveau la même DELETE http://example.com/account/123demande, le serveur répondra différemment, mais son état est le même.

Ce n'est pas comme si la demande DELETE a décidé de changer l'état du serveur d'une manière différente car le compte était manquant, comme la suppression d'un autre compte ou la suppression d'un journal des erreurs. Non, vous pouvez appeler la même requête DELETE un million de fois et vous pouvez être sûr que le serveur est dans le même état que la première fois que vous l'avez appelé .

Janac Meena
la source
7

À partir du RFC HTTP :

Les méthodes peuvent également avoir la propriété d '«idempotence» en ce que (à part les problèmes d'erreur ou d'expiration), les effets secondaires de N> 0 demandes identiques sont les mêmes que pour une seule demande.

Notez que ce sont des "effets secondaires" et non une "réponse".

fumanchu
la source
7

Oui. Quel que soit le code de réponse.

De la dernière RFC pour HTTP 1.1 (c'est moi qui souligne):

Les méthodes idempotentes se distinguent car la demande peut être répétée automatiquement si une erreur de communication se produit avant que le client ne puisse lire la réponse du serveur. Par exemple, si un client envoie une demande PUT et que la connexion sous-jacente est fermée avant qu'une réponse ne soit reçue, le client peut établir une nouvelle connexion et réessayer la demande idempotente. Il sait que la répétition de la demande aura le même effet prévu, même si la demande d'origine réussit, bien que la réponse puisse différer.

Il dit explicitement que la réponse pourrait différer. Plus important encore, il indique la raison du concept: si une action est idempotente, le client peut répéter l'action quand il rencontre une erreur, et sait qu'il ne plantera rien en le faisant; sinon, le client devra faire une requête supplémentaire (éventuellement GET) pour voir si la précédente est efficace, avant de répéter l'action en toute sécurité. Tant que le serveur peut faire une telle garantie, l'action est idempotente. Citation d' un autre commentaire :

Le calcul de l'idempotence concerne la robustesse d'un système. Puisque les choses peuvent échouer (par exemple, une panne de réseau), quand une panne est détectée, comment récupérez-vous? La récupération la plus simple est de simplement le refaire, mais cela ne fonctionne que si le faire à nouveau est idempotent. Par exemple, discard(x)est idempotent, mais pop()ne l'est pas. Tout est question de récupération d'erreur.

Franklin Yu
la source
2

Je pense la même chose, 404 - Le compte n'existe pas.

Vous pourriez argumenter 400 - Mauvaise demande. Mais dans le sens de REST, l'objet sur lequel vous avez demandé d'effectuer une action n'existe pas. Cela se traduit par 404.

Jason McCreary
la source
1
Pour générer un 400, vous devez savoir que l'objet existait auparavant, ce qui est très instable.
annakata
1
@annakata, 400 n'est même pas pour les ressources qui existaient auparavant (peut-être avez-vous 410 / Gone en tête), c'est pour les mauvaises requêtes "La requête n'a pas pu être comprise par le serveur en raison d'une syntaxe mal formée."
Bruno
3
@Bruno - Je sais ce que cela signifie, le PO l'a cité.
annakata
1
Je pense que 200 serait bien. Vous voulez que l'état du serveur soit que le compte a disparu. La demande qui l'a fait disparaître importe-t-elle? Il est toujours parti sur la deuxième demande, l'état du serveur n'a pas changé.
Andy
2

Cité de mon autre réponse ici :

Historiquement, la RFC 2616, publiée en 1999, était la spécification HTTP 1.1 la plus référencée. Malheureusement sa description de l'idempotence était vague , ce qui laisse place à tous ces débats. Mais cette spécification a été remplacée par la RFC 7231. Cité de la RFC 7231, section 4.2.2 Méthodes idempotentes , je souligne:

Une méthode de demande est considérée comme "idempotente" si l'EFFET prévu SUR LE SERVEUR de plusieurs demandes identiques avec cette méthode est le même que l'effet pour une seule demande de ce type. Parmi les méthodes de demande définies par cette spécification, les méthodes de demande PUT, DELETE et sûres sont idempotentes .

Donc, il est écrit dans les spécifications, l'idempotence est une question d'effet sur le serveur. Le premier DELETE renvoyant un 204 puis DELETE ultérieur renvoyant 404, un tel code d'état différent ne rend PAS le DELETE non idempotent. Utiliser cet argument pour justifier une déclaration 204 ultérieure n'est tout simplement pas pertinent.


OK donc il ne s'agit pas d'idempotence. Mais alors une question de suivi peut être, que se passe-t-il si nous choisissons toujours d'utiliser 204 dans DELETE ultérieur? Est-ce que c'est bon?

Bonne question. La motivation est compréhensible: permettre au client d'atteindre le résultat souhaité, sans se soucier de la gestion des erreurs. Je dirais que renvoyer 204 dans DELETE ultérieur est un "mensonge blanc" côté serveur largement inoffensif, dont le côté client ne fera pas immédiatement la différence. C'est pourquoi il y a des gens qui font cela dans la nature et cela fonctionne toujours. Gardez simplement à l'esprit qu'un tel mensonge peut être considéré comme sémantiquement bizarre, car "GET / non-exist" renvoie 404 mais "DELETE / non-exist" donne 204, à ce moment-là, le client comprendra que votre service n'est pas entièrement conforme section 6.5.4 404 introuvable .

Mais alors, la manière prévue suggérée par RFC 7231, c'est-à-dire renvoyer 404 lors de la suppression ultérieure, ne devrait pas être un problème en premier lieu. De nombreux autres développeurs ont choisi de le faire. C'est probablement parce que tout client qui implémente HTTP DELETE (ou toute méthode HTTP, d'ailleurs), ne supposerait pas aveuglément que le résultat serait toujours réussi 2xx. Et puis, une fois que le développeur commence à envisager la gestion des erreurs, 404 Not Found serait l'une des premières erreurs qui viendraient à l'esprit. À ce stade, il / elle en tirerait avec un peu de chance une conclusion selon laquelle il est sémantiquement sûr pour une opération HTTP DELETE d'ignorer une erreur 404. Problème résolu.

RayLuo
la source