Nous avons une URL au format suivant
/ instance / {instanceType} / {instanceId}
Vous pouvez l'appeler avec les méthodes HTTP standard: POST, GET, DELETE, PUT. Cependant, il y a quelques actions supplémentaires que nous prenons comme "Enregistrer comme brouillon" ou "Curate"
Nous pensions pouvoir utiliser des méthodes HTTP personnalisées telles que: DRAFT, VALIDATE, CURATE
Je pense que cela est acceptable puisque les normes disent
"L'ensemble des méthodes courantes pour HTTP / 1.1 est défini ci-dessous. Bien que cet ensemble puisse être développé, des méthodes supplémentaires ne peuvent pas être supposées partager la même sémantique pour des clients et des serveurs étendus séparément."
Et des outils tels que WebDav créent certaines de leurs propres extensions.
Existe-t-il des problèmes rencontrés par certaines méthodes personnalisées? Je pense aux serveurs proxy et aux pare-feu, mais toute autre préoccupation est la bienvenue. Devrais-je rester du côté sûr et avoir juste un paramètre d'URL tel que action = valider | curate | draft?
Réponses:
L'une des contraintes fondamentales de HTTP et de la fonctionnalité de conception centrale de REST est une interface uniforme fournie par (entre autres choses) un petit ensemble de méthodes fixes qui s'appliquent universellement à toutes les ressources. La contrainte d'interface uniforme présente un certain nombre de points positifs et négatifs. Je cite de Fielding libéralement ici.
Une interface uniforme:
D'autre part, une interface uniforme:
Les compromis sont "conçus pour le cas courant du Web" et ont permis la création d'un vaste écosystème offrant des solutions à de nombreux problèmes courants dans les architectures Web. L'adhésion à une interface uniforme permettra à votre système de tirer parti de cet écosystème, tandis que le rompre rendra la tâche plus difficile. Vous voudrez peut-être utiliser un équilibreur de charge tel que nginx, mais vous pouvez désormais utiliser uniquement un équilibreur de charge comprenant les fonctions DRAFT et CURATE. Vous voudrez peut-être utiliser une couche de cache HTTP comme Varnish, mais vous ne pouvez désormais utiliser qu'une couche de cache HTTP comprenant DRAFT et CURATE. Vous voudrez peut-être demander de l'aide à quelqu'un pour résoudre un problème de serveur mais personne d'autre ne connaît la sémantique d'une demande CURATE. Il peut être difficile de modifier les bibliothèques de vos clients ou serveurs préférés pour comprendre et implémenter correctement les nouvelles méthodes. Etc.
La bonne * façon de représenter c'est comme une transformation de l' Etat sur la ressource (ou de ressources connexes). Vous ne rédigez pas de publication, vous ne modifiez pas son
draft
étattrue
ou vous ne créez unedraft
ressource contenant les modifications et les liens vers les versions précédentes. Vous ne CURATEZ pas un message, vous transformez soncurated
état entrue
ou créez unecuration
ressource reliant le message à l'utilisateur qui l'a organisée.* Correct en ce sens qu'il suit le plus étroitement les principes architecturaux REST.
la source
Je préférerais les concevoir comme des sous-ressources, sur lesquelles vous effectuez une demande POST.
Considérons que vous avez une ressource sur
/instance/type/1
, je voudrais que la représentation de cette ressource transmette quelques liens vers des «actions» pouvant être effectuées sur la ressource, telles que/instance/type/1/draft
et/instance/type/1/curate
. En JSON, cela pourrait être aussi simple que:Cela permet au client d’être très explicite sur ce qui doit se passer lors de la demande POST au lien fourni par le
curate
membre. La ressource publiée ici pourrait inclure des arguments détaillant l'événement qui infligerait peut-être une transition d'état.L'adoption d'une approche «naïve» consistant à passer d'un état possible à l'autre d'une ressource présente l'inconvénient de ne pas capturer les événements qui ont conduit à ces transitions.
Les transitions d'état se produisent généralement en réponse à des événements spécifiques, et je préfère capturer ces événements plutôt que de laisser le client décider que quelque chose se trouve maintenant dans un "état" spécifique. Cela rend également la validation beaucoup plus difficile. De plus, vous ne pourrez capturer aucun «argument» à moins de décrire également ceux de l'état lui-même. Et puis cela devient tout nauséeux quand du code change ceux sans transition d'état réel, et la validation requise, et tout cela devient rapidement un gâchis.
la source
/vms/some-id
renvoie des liens vers des actions tellesPOST /vms/some-id/restart
que nous l’utilisons pour déterminer si les actions doivent être activées ou désactivées. J'ai une relation d'amour / haine avec HATEOAS :)Je pense que la méthode HTTP personnalisée est le meilleur moyen d'implémenter des actions d'entité. L'ajout de l'action au corps de l'entité (POST) ne semble pas correct, cela ne fait pas partie de votre entité (bien que le résultat puisse y être enregistré). De plus, en utilisant les méthodes HTTP personnalisées, les mandataires pourraient déterminer leurs actions sans avoir à analyser le corps de l'entité.
C'est comme CRUD, vous voudriez toujours les implémenter, mais vous avez également votre propre ensemble d'actions spécifiques (par entité). Je ne vois vraiment pas quel serait le problème pour les prolonger.
Aussi @Rein Henrichs "Vous ne rédigez pas de publication, vous transformez son état brouillon en vrai ou vous créez un brouillon", cela me semble faux. Une
drafts
propriété serait utilisée pour la sauvegarde persistante de l'état et non pour la transformation. Les actions ne donnent même pas nécessairement un "état", ni ne sont enregistrées dans une propriété. Créer une entité séparée pour chaque état / transformation semble encore plus flou. Essayez de conserver la même référence (URI) à l'entité.la source