REST, HTTP DELETE et parameters

Y a-t-il quelque chose de non-RESTful à propos de la fourniture de parameters à une requête HTTP DELETE?

Mon scénario est que je modélise le “Êtes-vous sûr de vouloir le supprimer?” scénario. Dans certains cas, l’état de la ressource suggère que la suppression demandée peut être invalide. Vous pouvez probablement imaginer vous-même certains scénarios où la confirmation d’une suppression est requirejse

La solution que nous avons adoptée consiste à passer un paramètre à la demande de suppression pour indiquer que la suppression est autorisée (“? Force_delete = true”)

par exemple

DELETE http://server/resource/id?force_delete=true 

Je crois que c’est toujours reposant puisque:

(a) La sémantique de DELETE n’est pas modifiée – l’utilisateur peut toujours envoyer une requête DELETE normale, mais cela peut échouer avec 409 et le corps de la réponse expliquera pourquoi. Je dis que peut échouer parce que (pour des raisons qui ne valent pas la peine d’être expliquées) à certaines occasions, il n’ya aucune raison d’inviter l’utilisateur.

(b) Il n’y a rien dans la thèse de Roy qui suggère que cela soit contraire à l’esprit de REST – pourquoi y aurait-il puisque HTTP n’est qu’une implémentation de REST alors pourquoi le passage des parameters HTTP importerait-il?

Quelqu’un peut-il m’indiquer une déclaration définitive qui explique la raison pour laquelle ce n’est pas RESTful?

Sur une question connexe, si l’utilisateur ne spécifie pas force_delete, alors je renvoie 409 Conflict – est-ce le code de réponse le plus approprié?

Suivre

Après quelques recherches supplémentaires, je pense que l’ajout de parameters au DELETE peut violer plusieurs principes.

La première est que l’implémentation viole éventuellement l’interface uniforme (voir la section 5.1.5 de la thèse de Roy).

En ajoutant “force_delete”, nous ajoutons une contrainte supplémentaire à la méthode DELETE déjà bien définie. Cette contrainte n’a de sens que pour nous.

Vous pourriez également faire valoir que cela viole le “client-serveur 5.1.2” car le dialog de confirmation est vraiment une préoccupation de l’interface utilisateur et que tous les clients ne voudront pas encore confirmer la suppression.

Suggestions à quelqu’un?

Non, ce n’est pas RESTful. La seule raison pour laquelle vous devriez placer un verbe ( force_delete ) dans l’URI est si vous devez surcharger les méthodes GET / POST dans un environnement où les méthodes PUT / DELETE ne sont pas disponibles. À en juger par l’utilisation de la méthode DELETE, ce n’est pas le cas.

Le code d’erreur HTTP 409/Conflict doit être utilisé pour les situations où un conflit empêche le service RESTful d’effectuer l’opération, mais il existe toujours un risque que l’utilisateur puisse résoudre le conflit lui-même. Une confirmation de pré-suppression (où il n’y a pas de conflit réel qui empêcherait la suppression) n’est pas un conflit en soi, car rien n’empêche l’API d’effectuer l’opération demandée.

Comme Alex l’a dit (je ne sais pas qui l’a refusé, il a raison), cela devrait être géré dans l’UI, car un service RESTful en tant que tel ne fait que traiter les demandes et doit donc être sans état (c.-à-d. toute information côté serveur concernant une demande).

Deux exemples de la façon de procéder dans l’interface utilisateur seraient les suivants:

  • pré-HTML5 : * affiche une boîte de dialog de confirmation JS à l’utilisateur et envoie la demande uniquement si l’utilisateur le confirme
  • HTML5 : * utiliser un formulaire avec l’action DELETE où le formulaire ne contiendrait que les boutons “Confirmer” et “Annuler” (“Confirmer” serait le bouton d’envoi)

(*) Veuillez noter que les versions HTML antérieures à 5 ne prennent pas en charge les méthodes HTTP PUT et DELETE, mais la plupart des navigateurs modernes peuvent utiliser ces deux méthodes via des appels AJAX. Voir cette discussion pour plus de détails sur la prise en charge entre navigateurs.


Mise à jour (basée sur une enquête et des discussions supplémentaires):

Le scénario dans lequel le service aurait besoin de l’ force_delete=true pour force_delete=true l’ interface uniforme définie dans la thèse de Roy Fielding. De même, selon la RFC HTTP , la méthode DELETE peut être remplacée sur le serveur d’origine (client), ce qui implique que cela n’est pas effectué sur le serveur cible (service).

Ainsi, une fois que le service reçoit une requête DELETE, il doit le traiter sans avoir besoin d’une confirmation supplémentaire (que le service effectue ou non l’opération).

Je pense que ce n’est pas reposant. Je ne pense pas que le service reposant devrait traiter l’obligation de forcer l’utilisateur à confirmer une suppression. Je gérerais cela dans l’interface utilisateur.

Est-ce que la spécification de force_delete = true a du sens s’il s’agissait d’une API de programme? Si quelqu’un écrivait un script pour supprimer cette ressource, voudriez-vous le forcer à spécifier force_delete = true pour supprimer réellement la ressource?

C’est une vieille question, mais voici quelques commentaires …

  1. En SQL, la commande DELETE accepte un paramètre “CASCADE”, qui vous permet de spécifier que les objects dépendants doivent également être supprimés. Ceci est un exemple de paramètre DELETE qui a du sens, mais “man rm” pourrait en fournir d’autres. Comment ces cas pourraient-ils être implémentés dans REST / HTTP sans paramètre?
  2. @Jan, il semble bien que la partie chemin de l’URL identifie une ressource, alors que la chaîne de requête n’en a pas (du moins pas nécessairement). Les exemples abondent: obtenir la même ressource mais dans un format différent, obtenir des champs spécifiques d’une ressource, etc. Si nous considérons la chaîne de requête comme faisant partie de l’identificateur de ressource, il est impossible d’avoir un concept de “vues différentes de la même ressource”. sans se tourner vers des mécanismes non-RESTful tels que la négociation de contenu HTTP (ce qui peut être indésirable pour de nombreuses raisons).

En plus de la réponse d’Alex:

Notez que http: // server / resource / id? Force_delete = true identifie une ressource différente de http: // server / resource / id . Par exemple, que vous supprimiez / customers /? Status = old ou / customers /, cela peut être une énorme différence.

Jan