web-dev-qa-db-fra.com

Quel verbe HTTP dois-je utiliser pour déclencher une action dans un service Web REST?

J'implémente un service Web RESTful et l'une des actions disponibles sera reload. Il sera utilisé pour recharger les configurations, le cache, etc.

Nous avons commencé avec un simple GET vers un URI comme ceci: ${path}/cache/reload (aucun paramètre n'est transmis, seul l'URI est appelé). Je suis conscient que les données ne doivent pas être modifiées avec une demande GET.

Quel est le verbe correct à utiliser pour appeler une action/commande dans un service Web RESTful?

Le rechargement est une commande du service Web REST qui recharge son propre cache/configuration/etc. Ce n'est pas une méthode qui renvoie des informations au client.

Ce que j'essaie de faire n'est probablement pas REST, mais c'est toujours quelque chose qui doit être fait de cette façon. Le reload La méthode n'était qu'un exemple réel qui avait du sens dans la portée de l'application et la plupart des réponses se concentraient sur elle, mais en fait, j'avais juste besoin de savoir quel verbe déclencher une action qui ne fait pas CRUD, mais qui change toujours les données/l'état .

J'ai trouvé cette réponse détaillée sur Stack Overflow sur le sujet: https://stackoverflow.com/questions/16877968/

91
Renato Dinhani

Je ne pense pas qu'il y ait un verbe approprié pour cette action car cette transaction n'est pas vraiment "RESTful". Le "s" et le "t" représentent le "transfert d'état" et rien n'est transféré ici. Ou, autrement dit, par la définition la plus stricte, les verbes comme PUT et POST sont toujours utilisés avec un nom et "recharger" a juste le verbe.

Ce rechargement peut ne pas être RESTful, mais il peut toujours être utile et vous n'aurez qu'à choisir un moyen de le faire et à vivre avec ou à expliquer que c'est inhabituel. GET est probablement le plus simple. Il y a cependant beaucoup de scepticisme dans les commentaires, alors vous devriez vous demander si cette action de rechargement est nécessaire ou non parce que quelque chose d'autre ne fait pas tout à fait ce qu'elle devrait faire.

26
Sean Redmond

Si vous voulez être RESTful, ne pensez pas au verbe pour effectuer une action, pensez à état dans lequel vous voulez que la ressource soit après que le client a fait quelque chose.

Donc, en utilisant l'un de vos exemples ci-dessus, vous avez une file d'attente de courriels qui envoie des courriels. Vous voulez que le client mette cette file d'attente d'e-mails en état de pause ou d'arrêt ou quelque chose.

Ainsi, le client met un nouvel état au serveur pour cette ressource. Cela peut être aussi simple que ce JSON

PUT http://myserver.com/services/email_service HTTP/1.1
Content-Type: text/json

{"status":"paused"}

Le serveur détermine comment passer de l'état actuel (par exemple, "en cours d'exécution") à l'état/état "en pause".

Si le client effectue un GET sur la ressource, il doit retourner l'état dans lequel il se trouve actuellement (par exemple, "en pause").

La raison de le faire de cette façon, et pourquoi REST peut être si puissant, c'est que vous laissez le COMMENT arriver à cet état sur le serveur.

Le client dit simplement "C'est l'état dans lequel vous devriez être maintenant" et le serveur détermine comment y parvenir. Il peut s'agir d'un simple retournement dans une base de données. Cela pourrait nécessiter des milliers d'actions. Le client s'en fiche et n'a pas besoin de le savoir.

Ainsi, vous pouvez complètement réécrire/repenser la façon dont le serveur fait cela et le client s'en fiche. Le client doit seulement être conscient des différents états (et de leurs représentations) d'une ressource, pas des internes.

78
Cormac Mulhall

Certaines des autres réponses, y compris celle acceptée, vous conseillent d'utiliser un GET (mais pas avec beaucoup d'enthousiasme).

Je ne suis pas d'accord.

Tout d'abord, tous les autres vous disent que ce n'est pas idéal et pas vraiment RESTful sont corrects. Dans un scénario RESTful approprié, vous manipulez des ressources sur le serveur et ajoutez, mettez à jour, supprimez, récupérez, etc. ces ressources. Un PUT doit envoyer une charge utile qui représente ce que la ressource devrait être lorsque la demande est terminée, et POST doit envoyer une charge utile qui représente une ressource à ajouter au serveur. Et un GET doit retourner une ressource sur le serveur.

Vous avez un RPC (appel de procédure distante), qui n'est pas RESTful - vous voulez FAIRE quelque chose sur le serveur. Donc, si vous essayez de créer une API purement RESTful, vous devriez reconsidérer ce que vous faites.

Cela dit, il faut parfois un peu contourner les règles. Surtout si vous développez une API interne qui ne sera pas exposée au public, vous pouvez décider que le compromis en vaut la peine.

Si vous le faites, je recommanderais un PUT ou un POST, selon que le RPC est ou non idempotent ou non.

En général, nous disons que HTTP PUT est mappé sur SQL UPDATE et que HTTP POST mappé sur SQL INSERT, mais ce n'est pas strictement vrai. HTTP POST ne doit pas nécessairement l'être. Cela signifie que vous pouvez appeler la même demande PUT autant de fois que vous le souhaitez sans effets secondaires. Une fois que vous l'avez appelée une fois, il est inoffensif de l'appeler Mais vous ne devez pas appeler de manière répétée les demandes POST sauf si vous avez l'intention de - chaque POST modifie à nouveau les données sur le serveur).

Dans votre cas, si vous avez besoin de cette fonction de rechargement, je recommanderais un PUT car il semble que ce soit idempotent. Mais je vous exhorte toujours à considérer ce que les autres ont dit à propos de ne pas en avoir besoin du tout.

33
Aaron Greenwald

POST et PUT sont les verbes HTTP utilisés pour soumettre une entité à un serveur Web. Avec PUT, l'entité soumise est la (nouvelle) représentation de la ressource à l'URI donné, qui ne correspond pas à ce que vous voulez. POST est pour le gestionnaire de formulaire traditionnel, où l'entité est des données auxiliaires pour la ressource, c'est donc le gagnant. L'entité comprendrait la commande ou l'action (par exemple, "action = reload").

Cela dit, la commande en question ne devrait probablement pas être exposée via une interface REST. Il semble que la nécessité de "recharger" se pose car les données peuvent être modifiées via un autre canal (par exemple, système de fichiers, Client DB). Les caches doivent être transparents. De plus, les requêtes HTTP doivent être atomiques, même en tenant compte des messages envoyés sur d'autres canaux. Offrir une commande de "rechargement" pour les paramètres de configuration semble une complexité inutile; nécessitant une conception fragile. Exposer " reload "pour nettoyer après une mise à jour via un autre canal est sale car un canal ne contient pas la conversation entière. Au lieu de cela, considérez l'un des:

  • effectuer des mises à jour entièrement via REST
  • exposer la ou les commandes à l'autre canal
  • automatiser les actions

Certaines de ces options pourraient ne pas être viables, selon les autres restrictions existantes.

Voir aussi " PUT vs POST in REST ".

6
outis

Je dirais pourquoi une demande client devrait explicitement passer un appel pour rafraîchir quelque chose comme ça. Il semble que cela devrait être soit une logique cachée sur une implémentation plus typique de GET (c'est-à-dire des données Pull, mais le service effectue un rafraîchissement sur les données avant qu'elles ne soient extraites), soit par un autre déclencheur dans le backend loin du client.

Après tout, les données/config n'auraient besoin d'être à jour que lors des appels suivants, donc je pencherais davantage vers un appel paresseux contre désireux pour un rafraîchissement des données. Évidemment, je suppose beaucoup ici, mais je prendrais un peu de recul pour réévaluer la nécessité d'un appel aussi explicite et autonome.

4
Thomas Stringer

Pourquoi ne pas traiter l'action comme une ressource. Donc, puisque vous voulez mettre à jour le cache, vous feriez POST une nouvelle action dans votre système.

Pour les puristes, vous pourriez avoir une URL dédiée pour cela. Notez que vous pouvez étendre cela et enregistrer les actions réelles dans une base de données (ou tout autre stockage) avec la date, le statut, l'utilisateur, etc ... Juste mes pensées ici.

Opération générique à l'échelle du système/actions/{action}

Opération spécifique à un type de ressource/actions/{ressource}/{action}

Opération spécifique à une ressource/actions/{ressource}/{id}/{action}

Dans votre cas, le cache est probablement à l'échelle du système/actions/reload_cache

3
Isometriq

Quel verbe HTTP dois-je utiliser pour déclencher une action dans un service Web REST?

Lorsque l'on considère les détails d'un service REST, il est souvent utile de considérer cette heuristique: comment implémenteriez-vous cela avec un site Web?

HTML ne peut décrire nativement que les requêtes GET et POST. Nous pouvons donc commencer la recherche là-bas.

GET est-il approprié? Pour répondre à cette question, nous devons réfléchir aux hypothèses que les clients et les composants intermédiaires sont autorisés à faire à propos de GET. La sémantique de GET est sûr

le client ne demande pas et n'attend pas de changement d'état sur le serveur Origin suite à l'application d'une méthode sûre à une ressource cible. De même, l'utilisation raisonnable d'une méthode sûre ne devrait pas causer de dommage, de perte de propriété ou de charge inhabituelle sur le serveur Origin.

L'implication, par conséquent, est que les clients et les composants intermédiaires ont le pouvoir discrétionnaire d'invoquer une demande GET aussi souvent que nécessaire pour satisfaire leurs propres préoccupations. Les araignées peuvent OBTENIR des ressources sans discernement pour mettre à jour leurs index. Les caches peuvent pré-récupérer. Sur un réseau peu fiable, les messages perdus peuvent être réessayés aussi souvent que nécessaire pour garantir au moins une réponse.

Il sera utilisé pour recharger les configurations, le cache, etc.

Si ce sont des choses coûteuses à faire, alors vous ne voulez peut-être pas que les clients émettent ces demandes à leur propre discrétion.

POST, d'un autre côté, n'est en fait pas contraint - cela réduit considérablement les hypothèses que les clients génériques sont autorisés à faire. Vous n'obtenez pas de composants faisant des demandes spéculatives POST car ils seraient défectueux - rien dans la norme ne dit que c'est OK.

PUT, PATCH, DELETE... ce sont des méthodes dangereuses avec une sémantique plus spécifique que POST; leur pertinence dépendra de votre modèle de ressources.

Une idée importante à garder à l'esprit est que les méthodes HTTP appartiennent au domaine du document (Voir exposé de Jim Webber 2011 ), les effets que vous décrivez ne font probablement pas partie du domaine du document, mais sont plutôt à côté effets invoqués lorsque les documents sont modifiés. Cela vous donne une grande liberté quant à la façon dont vous organisez vos documents pour faire le travail.

0
VoiceOfUnreason