web-dev-qa-db-fra.com

REST, HTTP DELETE et paramètres

Existe-t-il des éléments non RESTful concernant la fourniture de paramètres à une demande HTTP DELETE?


Mon scénario est que je modélise le "Êtes-vous sûr de vouloir supprimer ça?" 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 des scénarios où la confirmation d'une suppression est requise

La solution que nous avons adoptée consiste à passer un paramètre à la demande de suppression pour indiquer qu'il est correct de procéder à la suppression ("? Force_delete = true")

par exemple.

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

Je crois que c'est toujours reposant depuis:

(a) La sémantique de DELETE n'est pas modifiée - l'utilisateur peut toujours envoyer une demande DELETE normale mais ceci peut échouer avec 409 et le corps de la réponse expliquera pourquoi. Je dis peut échouer car (pour des raisons qui ne méritent pas d’être expliquées), il n’ya aucune raison d’inviter l’utilisateur.

(b) Rien dans la thèse de Roy n'indique que cela va à l'encontre de l'esprit de REST - pourquoi existerait-il puisque HTTP n'est qu'une implémentation de REST alors pourquoi le passage des paramètres HTTP est-il important


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

Sur une question connexe, si l'utilisateur ne spécifie pas force_delete, je retourne 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 paramètres à DELETE peut enfreindre plusieurs principes.

La première est que l'implémentation viole éventuellement "l'interface uniforme" (voir section 5.1.5 de 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 pouvez également faire valoir qu'il enfreint "5.1.2 Client-Serveur" car le dialogue de confirmation est réellement une préoccupation de l'interface utilisateur et que tous les clients ne voudront pas confirmer la suppression.

Suggestions quelqu'un?

126
Chris McCauley

Non, ce n'est pas reposant. La seule raison pour laquelle vous devriez mettre 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 votre utilisation de la méthode DELETE, ce n'est pas le cas.

Code d'erreur HTTP 409/Conflict devrait être utilisé dans les situations où un conflit empêche le service RESTful d’exécuter l’opération, mais il est toujours possible que l’utilisateur puisse résoudre le conflit lui-même. Une confirmation de pré-suppression (en l'absence de conflit réel empêchant 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 rétrogradé, il a raison), cela devrait être traité dans l'interface utilisateur, car un service RESTful en tant que tel traite juste les demandes et doit donc être apatride (c'est-à-dire qu'il ne doit pas s'appuyer sur des confirmations toute information côté serveur sur une requête).

Deux exemples d'utilisation de l'interface utilisateur sont les suivants:

  • pré-HTML5: * afficher une boîte de dialogue de confirmation JS à l'utilisateur et envoyer la demande uniquement si l'utilisateur le confirme
  • HTML5: * utiliser un formulaire avec l'action SUPPRIMER 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 à la version 5 ne prennent pas en charge les méthodes HTTP PUT et DELETE HTTP. Cependant, la plupart des navigateurs modernes peuvent effectuer ces deux méthodes via des appels AJAX. Voir ce fil pour plus de détails sur la prise en charge multi-navigateurs.


Mise à jour (sur la base d'enquêtes et de discussions supplémentaires):

Le scénario où le service nécessiterait le force_delete=true Le drapeau à être présent viole le interface uniforme tel que défini dans la thèse de Roy Fielding. De même, conformément à HTTP RFC , 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 demande DELETE, il devrait la traiter sans nécessiter de confirmation supplémentaire (que le service effectue réellement l'opération).

76
MicE

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

Spécifier force_delete = true a-t-il un 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 réellement supprimer la ressource?

34
Alex Rockwell

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 objets dépendants doivent également être supprimés. Ceci est un exemple de paramètre DELETE qui a du sens, mais 'man' peut en fournir d'autres. Comment ces cas pourraient-ils éventuellement être implémentés dans REST/HTTP sans paramètre?
  2. @ Jan, il semble être une convention bien établie que la partie chemin de l'URL identifie une ressource, contrairement à la chaîne de requête (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'identifiant de la ressource, il est impossible d'avoir un concept de "vues différentes de la même ressource". sans recourir à des mécanismes non-RESTful tels que la négociation de contenu HTTP (ce qui peut être indésirable pour de nombreuses raisons).
16
Shay Rojansky

En plus de la réponse d'Alex:

Notez que http: // serveur/ressource/id? Force_delete = true identifie une ressource différente de http: // serveur/ressource/id . Par exemple, si vous supprimez/clients /? Status = old ou/clients /, la différence est énorme.

Jan

5
Jan Algermissen