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éta-données supplémentaires dans le corps d'entité de la demande?
La spécification ne l'interdit pas explicitement ni ne la décourage, je dirais donc qu'elle est autorisée.
Microsoft le voit de la même manière (j'entends des murmures dans l'audience), comme indiqué dans l'article MSDN sur la méthode DELETE de 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) dit au sujet des demandes:
Content-Length
ou Transfer-Encoding
(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 contenue dans un message de demande DELETE n'a pas de sémantique définie; l'envoi d'un corps de données utiles sur une demande DELETE peut amener certaines implémentations existantes à rejeter la demande.
Certaines versions de Tomcat et Jetty semblent ignorer un corps d'entité s'il est présent. Ce qui peut être une nuisance si vous aviez l'intention de le recevoir.
Une des raisons d'utiliser le corps dans une demande de suppression est le contrôle optimiste de la concurrence.
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 compte rendu.
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, ce 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 le compte rendu, voyez qu'il est important, et ne le supprimez peut-être pas.
Une autre raison de l'utiliser consiste à supprimer plusieurs enregistrements à la fois (par exemple, une grille avec des cases à cocher pour la sélection de lignes).
DELETE /messages
[{id:1, version:2},
{id:99, version:3}]
204 No Content
Notez que chaque message a sa propre version. Peut-être que vous pouvez 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), éventuellement avec des versions antérieures également:
@RestController
public class TestController {
@RequestMapping(value="/echo-delete", method = RequestMethod.DELETE)
SomeBean echoDelete(@RequestBody SomeBean someBean) {
return someBean;
}
}
Il me semble que RFC 2616 ne le précise pas.
De la section 4.3:
La présence d'un corps de message dans une requête est signalée par le inclusion d'un champ d'en-tête Content-Length ou Transfer-Encoding dans les en-têtes de la requête. Un corps de message NE DOIT PAS être inclus dans une demande si la spécification de la méthode de la demande (section 5.1.1) n'autorise pas l'envoi d'un corps d'entité dans les requêtes. Un serveur DEVRAIT lire et transférer un corps de message pour toute demande; si la méthode de la demande n'inclut pas la sémantique définie pour un corps d'entité, alors le Le corps du message DEVRAIT être ignoré lors du traitement de la demande.
Et la section 9.7:
La méthode DELETE demande au serveur d'origine de supprimer la ressource identifié par l'URI de la demande. Cette méthode PEUT être remplacée par human intervention (ou autre moyen) sur le serveur Origin. Le client ne peut pas être assuré que l'opération a été effectuée, même si le Le code d'état renvoyé par le serveur d'origine indique que l'action a été complété avec succès. Cependant, le serveur NE DEVRAIT PAS indiquer le 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 fichier inaccessible emplacement.
Une réponse réussie DEVRAIT être 200 (OK) si la réponse inclut un entité décrivant le statut, 202 (accepté) si l'action n'a pas encore été adopté, ou 204 (pas de contenu) si l'action a été adoptée mais la réponse n'inclut pas une entité.
Si la demande passe par un cache et que l'URL de demande identifie une ou plusieurs entités actuellement mises en cache, ces entrées DEVRAIENT être traité comme rassis. Les réponses à cette méthode ne sont pas cacheable.c
Donc, ce n'est pas explicitement autorisé ou interdit, et il est possible qu'un proxy en cours de route supprime le corps du message (même s'il DEVRAIT le lire et le transférer).
Juste un avertissement, si vous fournissez un corps dans votre demande DELETE et 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 découvris que pour une raison quelconque, Google considère qu'une requête DELETE avec un corps est une requête mal formée.
Il semble que ElasticSearch utilise ceci: https://www.elastic.co/guide/fr/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
Ceci n'est pas défini.
Une charge utile contenue dans un message de demande DELETE n'a pas de sémantique définie; l'envoi d'un corps de données utiles sur une demande DELETE peut entraîner l'apparition de fichiers implémentations pour rejeter la demande.
https://tools.ietf.org/html/rfc7231#page-29
Si quelqu'un teste ce 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 corporelles fournies (une grande liste d'identifiants à supprimer en bloc, conformément à la conception des terminaux).
Je les ai contactés à plusieurs reprises et leur ai envoyé trois paquets distincts de scripts, d'images et de journaux qu'ils doivent consulter et ils ne l'ont toujours pas confirmé. Un correctif a échoué, et une téléconférence manquée de leur soutien plus tard et je n'ai toujours pas eu de réponse solide.
Je suis certain que Sahi ne supporte pas cela, et j'imagine que de nombreux autres outils suivent.
Je ne pense pas qu'une bonne réponse à cela ait été postée, bien qu'il y ait eu beaucoup d'excellents commentaires sur les réponses existantes. Je vais soulever l'essentiel de ces commentaires dans une nouvelle réponse:
Ce paragraphe de RFC7231 a été cité plusieurs fois, ce qui le résume.
Une charge utile contenue dans un message de demande DELETE n'a pas de sémantique définie; l'envoi d'un corps de données utiles sur une demande DELETE peut entraîner le rejet de la demande par certaines implémentations existantes.
Ce qui me manquait des autres réponses était l'implication. Oui, il est permis d'inclure un corps dans les requêtes DELETE
, mais cela n'a pas de sens sémantique. Cela signifie réellement qu'émettre une demande DELETE
avec un corps de demande équivaut sémantiquement à ne pas inclure un corps de demande.
L'inclusion d'un corps de requête ne devrait avoir aucun effet sur la requête, il est donc inutile de l'inclure.
tl; dr: Techiciquement, une requête DELETE
avec un corps de requête est autorisée, mais il n’est jamais utile de le faire.
J'ai pu implémenter l'opération DELETE avec un corps de requête. J'ai utilisé AWS Lambda et la passerelle API AWS, ainsi que le langage Go.
Utiliser DELETE avec un corps est risqué ... Je préfère cette approche pour les opérations sur les listes plutôt que sur REST:
Opérations régulières
GET/objects/ Obtient tous les objets
GET/object /ID Obtient un objet avec l'ID spécifié
POST/objects 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 travailler normalement.