Lors de l'émission d'une requête HTTP DELETE, l'URI de la requête doit identifier complètement la ressource à supprimer. Cependant, est-il permis d'ajouter des métadonnées supplémentaires dans le cadre du corps d'entité de la demande?
Lors de l'émission d'une requête HTTP DELETE, l'URI de la requête doit identifier complètement la ressource à supprimer. Cependant, est-il permis d'ajouter des métadonnées supplémentaires dans le cadre du corps d'entité de la demande?
Réponses:
La spécification ne l'interdit ni ne la décourage explicitement, j'ai donc tendance à dire qu'elle est autorisée.
Microsoft le voit de la même manière (j'entends des murmures dans le public), ils déclarent dans l'article MSDN sur la méthode DELETE d'ADO.NET Data Services Framework :
Si une demande DELETE inclut un corps d'entité, le corps est ignoré [...]
De plus, voici ce que RFC2616 (HTTP 1.1) a à dire en ce qui concerne les demandes:
Content-Length
ou d' un en - Transfer-Encoding
tête (section 4.3)Pour les réponses, cela a été défini:
La dernière mise à jour de la spécification HTTP 1.1 ( RFC 7231 ) autorise explicitement un corps d'entité dans une demande DELETE:
Une charge utile dans un message de demande DELETE n'a pas de sémantique définie; l'envoi d'un corps de charge utile sur une demande DELETE peut entraîner le rejet de la demande par certaines implémentations existantes.
A payload within a DELETE request message has no defined semantics; sending a payload body on a DELETE request might cause some existing implementations to reject the request.
il est donc livré avec un avertissement de compatibilité descendante, il suggère que la prochaine norme dira: `` oui! DELETE
peut avoir un corps ».
A payload within a DELETE request message has no defined semantics
. Le corps est donc autorisé.
Certaines versions de Tomcat et Jetty semblent ignorer un corps d'entité s'il est présent. Ce qui peut être gênant si vous aviez l'intention de le recevoir.
L'une des raisons d'utiliser le corps dans une demande de suppression est un contrôle de concurrence optimiste.
Vous lisez la version 1 d'un enregistrement.
GET /some-resource/1
200 OK { id:1, status:"unimportant", version:1 }
Votre collègue lit la version 1 du dossier.
GET /some-resource/1
200 OK { id:1, status:"unimportant", version:1 }
Votre collègue modifie l'enregistrement et met à jour la base de données, qui met à jour la version à 2:
PUT /some-resource/1 { id:1, status:"important", version:1 }
200 OK { id:1, status:"important", version:2 }
Vous essayez de supprimer l'enregistrement:
DELETE /some-resource/1 { id:1, version:1 }
409 Conflict
Vous devriez obtenir une exception de verrouillage optimiste. Relisez l'enregistrement, voyez qu'il est important et ne le supprimez peut-être pas.
Une autre raison de l'utiliser est de supprimer plusieurs enregistrements à la fois (par exemple, une grille avec des cases à cocher de sélection de ligne).
DELETE /messages
[{id:1, version:2},
{id:99, version:3}]
204 No Content
Notez que chaque message a sa propre version. Vous pouvez peut-être spécifier plusieurs versions en utilisant plusieurs en-têtes, mais par George, c'est plus simple et beaucoup plus pratique.
Cela fonctionne dans Tomcat (7.0.52) et Spring MVC (4.05), peut-être aussi avec des versions antérieures:
@RestController
public class TestController {
@RequestMapping(value="/echo-delete", method = RequestMethod.DELETE)
SomeBean echoDelete(@RequestBody SomeBean someBean) {
return someBean;
}
}
If-Unmodified-Since
ou Etag
, c'est à cela qu'elles sont destinées).
Il me semble que la RFC 2616 ne le précise pas.
De la section 4.3:
La présence d'un corps de message dans une demande est signalée par l'inclusion d'un champ d'en-tête Content-Length ou Transfer-Encoding dans les en-têtes de message de la demande. Un corps de message NE DOIT PAS être inclus dans une demande si la spécification de la méthode de demande (section 5.1.1) ne permet pas d'envoyer un corps d'entité dans les demandes. Un serveur DEVRAIT lire et transmettre un corps de message sur toute demande; si la méthode de demande n'inclut pas de sémantique définie pour un corps d'entité, alors le corps du message DEVRAIT être ignoré lors du traitement de la demande.
Et l'article 9.7:
La méthode DELETE demande au serveur d'origine de supprimer la ressource identifiée par l'URI de demande. Cette méthode PEUT être remplacée par une intervention humaine (ou tout autre moyen) sur le serveur d'origine. Le client ne peut pas garantir que l'opération a été effectuée, même si le code d'état renvoyé par le serveur d'origine indique que l'action s'est terminée avec succès. Cependant, le serveur NE DEVRAIT PAS indiquer de succès sauf si, au moment où la réponse est donnée, il a l'intention de supprimer la ressource ou de la déplacer vers un emplacement inaccessible.
Une réponse réussie DEVRAIT être 200 (OK) si la réponse comprend une entité décrivant le statut, 202 (Accepté) si l'action n'a pas encore été exécutée, ou 204 (Pas de contenu) si l'action a été exécutée mais la réponse ne comprend pas une entité.
Si la demande passe par un cache et que l'URI de demande identifie une ou plusieurs entités actuellement mises en cache, ces entrées DEVRAIENT être traitées comme périmées. Les réponses à cette méthode ne peuvent pas être mises en cache.c
Il n'est donc pas explicitement autorisé ou interdit, et il est possible qu'un proxy en cours de route supprime le corps du message (bien qu'il DEVRAIT le lire et le transmettre).
Attention, si vous fournissez un corps dans votre demande DELETE et que vous utilisez un équilibreur de charge Google Cloud HTTPS, il rejettera votre demande avec une erreur 400. Je me cognais la tête contre un mur et j'ai découvert que Google, pour une raison quelconque, pense qu'une demande DELETE avec un corps est une demande mal formée.
for whatever reason
- parce que la spécification le dit: P
DELETE
est le dernier.
Il semble qu'ElasticSearch utilise ceci: https://www.elastic.co/guide/en/elasticsearch/reference/5.x/search-request-scroll.html#_clear_scroll_api
Ce qui signifie que Netty soutient cela.
Comme mentionné dans les commentaires, il se peut que ce ne soit plus le cas
Roy Fielding sur la liste de diffusion HTTP précise que sur la liste de diffusion http https://lists.w3.org/Archives/Public/ietf-http-wg/2020JanMar/0123.html et dit:
Il est absolument interdit aux organismes GET / DELETE d'avoir un quelconque impact sur le traitement ou l'interprétation de la demande
Cela signifie que le corps ne doit pas modifier le comportement du serveur. Il ajoute ensuite:
mis à part la nécessité de lire et de rejeter les octets reçus afin de maintenir le cadrage du message.
Et enfin la raison de ne pas interdire le corps:
La seule raison pour laquelle nous n'avons pas interdit l'envoi d'un corps est que cela conduirait à des implémentations paresseuses en supposant qu'aucun corps ne serait envoyé.
Ainsi, alors que les clients peuvent envoyer le corps de la charge utile, les serveurs doivent le supprimer et les API ne doivent pas définir de sémantique pour le corps de la charge utile sur ces demandes.
Ce n'est pas défini .
Une charge utile dans un message de demande DELETE n'a pas de sémantique définie; l'envoi d'un corps de charge utile sur une demande DELETE peut entraîner le rejet de la demande par certaines implémentations existantes.
https://tools.ietf.org/html/rfc7231#page-29
L'utilisation de DELETE avec un corps est risquée ... Je préfère cette approche pour les opérations de liste à REST:
Opérations régulières
GET / objets / Obtient tous les objets
GET / objet / ID Obtient un objet avec l'ID spécifié
POST / objets Ajoute un nouvel objet
PUT / object / ID Ajoute un objet avec l'ID spécifié, met à jour un objet
DELETE / object / ID Supprime l'objet avec l'ID spécifié
Toutes les actions personnalisées sont POST
POST / objects / addList Ajoute une liste ou un tableau d'objets inclus dans le corps
POST / objects / deleteList Supprime une liste d'objets inclus dans le corps
POST / objects / customQuery Crée une liste basée sur une requête personnalisée dans le corps
Si un client ne prend pas en charge vos opérations étendues, il peut fonctionner de manière régulière.
POST
n'est pas un bon moyen RESTy pour créer de nouvelles ressources car la sémantique des réponses POST n'est pas claire, en particulier dans le contexte des en-têtes Location. Vous laissez essentiellement HTTP derrière et empilez RPC sur le dessus. La "méthode HTTP / REST" appropriée est de créer des ressources en utilisant PUT
w / l'en- If-None-Match: *
tête (ou en spécifiant les méthodes HTTP appropriées, voir MKCOL
etc.).
Je ne pense pas qu'une bonne réponse à cela ait été publiée, bien qu'il y ait eu beaucoup de bons commentaires sur les réponses existantes. Je vais lever l'essentiel de ces commentaires dans une nouvelle réponse:
Ce paragraphe de la RFC7231 a été cité à plusieurs reprises, ce qui le résume.
Une charge utile dans un message de demande DELETE n'a pas de sémantique définie; l'envoi d'un corps de charge utile sur une demande DELETE peut entraîner le rejet de la demande par certaines implémentations existantes.
Ce que j'ai manqué des autres réponses était l'implication. Oui, il est autorisé d'inclure un corps sur les DELETE
demandes, mais cela n'a pas de sens sémantique. Ce que cela signifie vraiment, c'est que l'émission d'unDELETE
demande avec un corps de demande équivaut sémantiquement à ne pas inclure de corps de demande.
L'inclusion d'un corps de demande ne devrait pas avoir d'effet sur la demande, il n'y a donc aucun intérêt à l'inclure.
tl; dr: Techniquement, une DELETE
demande avec un corps de demande est autorisée, mais ce n'est jamais utile de le faire.
Dans le cas où quelqu'un se heurte à ce test de problème, non, il n'est pas universellement pris en charge.
Je teste actuellement avec Sahi Pro et il est très évident qu'un appel http DELETE supprime toutes les données de corps fournies (une grande liste d'ID à supprimer en vrac selon la conception du point de terminaison).
J'ai été en contact avec eux plusieurs fois et j'ai envoyé trois paquets distincts de scripts, d'images et de journaux pour qu'ils les examinent et ils ne l'ont toujours pas confirmé. Un patch échoué, et une conférence téléphonique manquée par leur support plus tard et je n'ai toujours pas obtenu de réponse solide.
Je suis certain que Sahi ne supporte pas cela, et j'imagine que de nombreux autres outils suivent la suite.
L'URL GitHUb ci-dessous pourrait vous aider à obtenir la réponse. En fait, Application Server comme Tomcat, Weblogic refusant l'appel HTTP.DELETE avec la charge utile de la demande. Donc, en gardant ces choses à l'esprit, j'ai ajouté un exemple dans github, veuillez jeter un œil à cela