J'ai du mal à déterminer comment concevoir des URL reposantes. Je suis tout à fait pour l'approche reposante de l'utilisation d'URL avec des noms et non des verbes, je ne comprends pas comment faire cela.
Nous créons un service pour implémenter une calculatrice financière. La calculatrice prend un tas de paramètres que nous téléchargerons via un fichier CSV. Les cas d'utilisation impliqueraient:
- Télécharger de nouveaux paramètres
- Obtenez les derniers paramètres
- Obtenir des paramètres pour une date commerciale donnée
- Rendre un ensemble de paramètres actif
- Valider un ensemble de paramètres
Je suppose que l'approche reposante serait d'avoir les URL de type suivantes:
/parameters
/parameters/12-23-2009
Vous pouvez obtenir les trois premiers cas d'utilisation avec:
- POST où vous incluez le fichier de paramètres dans la demande de publication
- OBTENIR la première URL
- OBTENIR la deuxième URL
Mais comment faites-vous les 4e et 5e cas d'utilisation sans verbe? N'auriez-vous pas besoin d'URL comme:
/parameters/ID/activate
/parameters/ID/validate
??
rest
restful-url
Marcus Leon
la source
la source
Réponses:
Peut-être quelque chose comme:
la source
POST
est OK si vous devez effectuer une "procédure" comme vérifier les paramètres à chaque fois que vous envoyez une demande. Mais lorsque vous modifiez l'état (d'application) de la ressource, vous mettez réellement à jour la ressource existante, ne créez pas de nouvelle ressource ou ne postez pas de demande de traitement.POST
vsPUT
n'est pas exactement commeinsert
vsupdate
.PUT
met à jour la ressource correspondant au chemin donné ou crée une nouvelle ressource correspondant au chemin donné.POST
crée une nouvelle ressource quelque part. Par exemple,PUT /blog/posts/3/comments/5
mettra à jour le commentaire approprié, tandis quePOST /blog/posts/3/comments
créera une nouvellecomment
ressource (et devrait retourner le chemin d'accès à la nouvelle ressource dans la réponse).PUT
est idempotente alors qu'ellePOST
ne l'est pas. Habituellement, vous devez mettre autant de contraintes que possible sur ce que vous fournissez. Rester avecPUT
donne plus d'informations au client du service.Principes généraux pour une bonne conception d'URI:
/resource
ou/resource/
; créer 301 redirections à partir de celle que vous n'utilisez pas(Remarque: je n'ai pas dit "Conception d'URI RESTful"; les URI sont essentiellement opaques dans REST.)
Principes généraux pour le choix de la méthode HTTP:
Principes généraux de la conception de services Web avec HTTP:
201 Created
après avoir créé une ressource; la ressource doit exister au moment de l'envoi de la réponse202 Accepted
après avoir effectué une opération avec succès ou créé une ressource de manière asynchrone400 Bad Request
quand quelqu'un fait une opération sur des données qui est clairement fausse; cela pourrait être une erreur de validation pour votre application; réserver généralement 500 pour les exceptions non capturées401 Unauthorized
lorsque quelqu'un accède à votre API sans fournir un en-Authorization
tête nécessaire ou lorsque les informations d'identification dans leAuthorization
sont invalides; n'utilisez pas ce code de réponse si vous n'attendez pas d'informations d'identification via un en-Authorization
tête.403 Forbidden
quand quelqu'un accède à votre API d'une manière qui pourrait être malveillante ou s'il n'est pas autorisé405 Method Not Allowed
quand quelqu'un utilise POST alors qu'il aurait dû utiliser PUT, etc.413 Request Entity Too Large
lorsque quelqu'un tente de vous envoyer un fichier trop volumineux418 I'm a teapot
lorsque vous essayez de préparer du café avec une théièreETag
les en-têtes sont bons lorsque vous pouvez facilement réduire une ressource à une valeur de hachageLast-Modified
devrait vous indiquer que le respect d'un horodatage de la mise à jour des ressources est une bonne idéeCache-Control
etExpires
devrait recevoir des valeurs sensiblesIf-None-Modified
,If-Modified-Since
)En ce qui concerne votre question spécifique, POST doit être utilisé pour # 4 et # 5. Ces opérations relèvent de la directive "RPC-like" ci-dessus. Pour le n ° 5, n'oubliez pas que POST ne doit pas nécessairement être utilisé
Content-Type: application/x-www-form-urlencoded
. Cela pourrait tout aussi bien être une charge utile JSON ou CSV.la source
Chaque fois qu'il semble que vous ayez besoin d'un nouveau verbe, pensez plutôt à transformer ce verbe en nom. Par exemple, transformez «activer» en «activation» et «valider» en «validation».
Mais d'après ce que vous avez écrit, je dirais que votre application a des problèmes beaucoup plus importants.
Chaque fois qu'une ressource appelée «paramètre» est proposée, elle devrait envoyer des signaux d'alarme dans l'esprit de chaque membre de l'équipe de projet. 'paramètre' peut littéralement s'appliquer à n'importe quelle ressource; ce n'est pas assez précis.
Que représente exactement un «paramètre»? Probablement un certain nombre de choses différentes, dont chacune devrait avoir une ressource distincte qui lui est dédiée.
Une autre façon d'y parvenir - lorsque vous discutez de votre application avec des utilisateurs finaux (ceux qui connaissent probablement peu la programmation), quels sont les mots qu'ils utilisent eux-mêmes à plusieurs reprises?
Ce sont les mots autour desquels vous devriez concevoir votre application.
Si vous n'avez pas encore eu cette conversion avec des utilisateurs potentiels - arrêtez tout maintenant et n'écrivez pas une autre ligne de code avant de le faire! Ce n'est qu'alors que votre équipe aura une idée de ce qui doit être construit.
Je ne connais rien au logiciel financier, mais si je devais deviner, je dirais que certaines des ressources pourraient s'appeler par exemple "Rapport", "Paiement", "Transfert" et "Devise".
Il existe un certain nombre de bons livres sur cette partie du processus de conception de logiciels. Deux que je peux recommander sont les modèles de conception et d' analyse pilotés par domaine .
la source
La conception de vos URL n'a rien à voir avec le fait que votre application soit RESTful ou non. L'expression "URL RESTful" est donc un non-sens.
Je pense que vous devriez lire davantage sur ce qu'est réellement REST. REST traite les URL comme opaques et, en tant que tels, ne sait pas ce qu'ils contiennent, qu'il y ait des verbes ou des noms ou autre. Vous voudrez peut-être toujours concevoir vos URL, mais cela concerne l'interface utilisateur, pas REST.
Cela dit, passons à votre question: les deux derniers cas ne sont pas RESTful et ne correspondent à aucun type de schéma reposant. C'est ce que vous pourriez appeler RPC. Si vous êtes sérieux au sujet de REST, vous devrez repenser le fonctionnement de votre application à partir de zéro. Soit cela, soit abandonnez REST et faites simplement votre application en tant qu'application RPC.
Hrmmm peut-être pas.
L'idée ici est que vous devez tout traiter comme une ressource, donc une fois qu'un ensemble de paramètres a une URL à partir de laquelle vous pouvez vous y référer, vous ajoutez simplement:
Mais encore une fois, cette chose d'activation est RPC, pas REST.
la source
Les exigences d'activation et de validation sont des situations dans lesquelles vous essayez de modifier l'état d'une ressource. Ce n'est pas différent que de passer une commande "achevée" ou une autre demande "soumise". Il existe de nombreuses façons de modéliser ces types de changement d'état, mais celle que je trouve qui fonctionne souvent consiste à créer des ressources de collection pour les ressources du même état, puis à déplacer la ressource entre les collections pour affecter l'état.
par exemple, créer des ressources telles que,
Si vous souhaitez activer un ensemble de paramètres, ajoutez cet ensemble à la collection ActiveParameters. Vous pouvez soit passer l'ensemble de paramètres en tant que corps d'entité, soit passer une URL en tant que paramètre de requête, comme suit:
La même chose peut être faite avec les / ValidatedParameters. Si les paramètres ne sont pas valides, le serveur peut renvoyer "Bad Request" à la demande pour ajouter les paramètres à la collection de paramètres validés.
la source
Je suggère la ressource et les méthodes Meta suivantes.
Activez et / ou validez les paramètres:
Vérifiez si les paramètres sont actifs et valides:
la source
Je suis un peu triste de voir qu'après plus de 10 ans, il n'y a pas de réponse indiquant vraiment comment une chose telle que demandée dans l'OP pourrait être conçue dans une architecture REST, donc je ressens le besoin de le faire maintenant.
Tout d'abord, qu'est-ce que REST?! L'acronyme REST ou ReST signifie "Representational State Transfer" et définit l'échange de l'état d'une ressource dans un certain format de représentation. Le format de représentation est conforme au type de média négocié. Dans le cas de
application/html
format de représentation, il peut y avoir un flux de contenu texte au format HTML qui est rendu dans le navigateur, probablement après avoir appliqué une mise en forme de feuille de style pour positionner certains éléments à certains emplacements.REST est en principe une généralisation du Web navigable que nous connaissons tous, bien qu'il cible toutes sortes d'applications et pas seulement les navigateurs. Par conséquent, de par leur conception, les mêmes concepts qui s'appliquent au Web s'appliquent également à une architecture REST. Une question comme comment réaliser quelque chose d'une manière "RESTful" résout la réponse à la question comment réaliser quelque chose sur une page Web et ensuite appliquer les mêmes concepts sur la couche d'application.
Une calculatrice basée sur le Web peut généralement commencer par une "page" qui vous permet de saisir des valeurs à calculer avant d'envoyer les données saisies au serveur. En HTML, cela est généralement réalisé via des
<form>
éléments HTML qui apprennent au client les paramètres disponibles à définir, l'emplacement cible auquel envoyer la demande ainsi que le format de représentation à appliquer lors de l'envoi des données d'entrée. Cela peut ressembler à ceci:L'exemple ci-dessus indique qu'il y a deux champs d'entrée qui peuvent être remplis soit par l'utilisateur soit par d'autres automates, et qu'en invoquant l'élément d'entrée de soumission, le navigateur prend soin de formater les données d'entrée dans un
application/x-www-form-urlencoded
format de représentation qui est envoyé à l'emplacement cible mentionné via la méthode de requête HTTP spécifiée,POST
dans ce cas. Si nous entrons1
dans lefirstNumber
champ de saisie et2
dans lesecondNumber
champ de saisie, le navigateur va générer une représentationfirstNumber=1&secondNumber=2
et l'envoyer en tant que charge utile du corps de la demande réelle à la ressource cible.La requête HTTP brute envoyée au serveur peut donc ressembler à ceci:
Le serveur peut effectuer le calcul et répondre avec une autre page HTML contenant le résultat du calcul, car la demande a indiqué que le client comprend ce format.
Comme Breton l'a déjà souligné, il n'existe pas d'URL ou d'URI "RESTful". Un URI / URL est son propre genre de chose et ne devrait pas donner de sens à un client / utilisateur. Dans l'exemple de calculatrice ci-dessus, un utilisateur n'est tout simplement pas intéressé par l'endroit où lui envoyer les données. Il souhaite simplement que lors du déclenchement du champ d'entrée de soumission, la demande soit envoyée. Toutes les informations requises pour effectuer la tâche doivent déjà être fournies par le serveur.
Un navigateur peut également ne pas être conscient du fait que la demande alimente en fait une calculatrice avec certains paramètres d'entrée, il pourrait aussi bien s'agir d'une sorte de formulaire de commande qui renvoie uniquement la représentation de formulaire suivante pour continuer le processus de commande ou d'un type totalement différent de Ressource. Il effectue simplement ce que la spécification HTML exige dans un tel cas et il se fiche de ce que fait réellement le serveur. Ce concept permet à un navigateur d'utiliser le même format de représentation pour faire toutes sortes de choses telles que commander des choses dans votre boutique en ligne préférée, discuter avec vos meilleurs amis, vous connecter à un compte en ligne, etc.
L' abordabilité de certains éléments, comme dans le cas du champ de saisie de soumission qui est généralement rendu sous forme de bouton, définit ce que vous devez en faire. Dans le cas d'un bouton ou d'un lien, il vous demande essentiellement de cliquer dessus. D'autres éléments peuvent transmettre des opportunités différentes. Une telle possibilité peut également s'exprimer via des relations de lien de , c'est-à-dire avec
preload
des liens annotés qui indiquent essentiellement à un client qu'il peut déjà charger le contenu de la ressource liée en arrière-plan, car l'utilisateur saisira très probablement ce contenu ensuite. De telles relations de liens doivent bien sûr être standardisées ou suivre le mécanisme d'extension pour les types de relations tels que définis par les liens Web .Ce sont les concepts fondamentaux qui sont utilisés sur le Web et qui devraient également être utilisés dans une architecture REST. Selon "l'Oncle Bob" Robert C. Martin, une architecture est une intention et l'intention derrière l'architecture REST est le découplage des clients des serveurs pour permettre aux serveurs d'évoluer librement à l'avenir sans avoir à craindre de casser des clients. Cela nécessite malheureusement beaucoup de discipline car il est si facile d'introduire le couplage ou d'ajouter des solutions rapides pour faire le travail et passer à autre chose. Comme l'a souligné Jim Webber dans une architecture REST, vous, en tant que fournisseur de services, devez essayer de concevoir un protocole d'application de domaine similaire à un jeu informatique textuel des années 70 que les clients suivront jusqu'à la fin d'un processus.
Ce que de nombreuses API dites «REST» font malheureusement en réalité, c'est tout sauf cela. Vous voyez l'échange de données basées principalement sur JSON qui est spécifié dans une documentation externe spécifique à l'API qui est généralement difficile à intégrer dynamiquement à la volée. Le format auquel une demande doit ressembler est également codé en dur dans la documentation externe, ce qui conduit à de nombreuses URI d'interprétation d'implémentation pour renvoyer des types prédéfinisau lieu d'utiliser un format de représentation commun qui est négocié à l'avance. Cela empêche les serveurs de changer car les clients s'attendent maintenant à recevoir un certain format de données (notez pas le format de représentation!) Pour les URI prédéfinis. Cet échange de format de données personnalisé empêche en outre les clients d'interagir avec d'autres API car le "format de données" est généralement associé à une API spécifique. Nous connaissons ce concept du passé grâce aux technologies RPC telles que Corba, RMI ou SOAP que nous condamnons comme étant en quelque sorte maléfiques, même si Peppol y est retourné en remplaçant AS2 par AS4 comme protocole de transfert par défaut récemment.
En ce qui concerne la question posée, l'envoi de données sous forme de fichier csv n'est pas différent de l'utilisation d'une
application/x-www-form-urlencoded
représentation ou de choses similaires. Jim Webber a précisé qu'après tout, HTTP n'est qu'un protocole de transport dont le domaine d'application est le transfert de documents sur le Web . Le client et le serveur doivent au moins tous deux prendretext/csv
en charge comme défini dans la RFC 7111 . Ce fichier CSV pourrait être généré à la suite du traitement d'un type de média qui définit des éléments de formulaire, un élément cible ou un attribut auquel envoyer la demande ainsi que la méthode HTTP pour effectuer le téléchargement de la configuration.Il existe quelques types de supports qui prennent en charge des formulaires tels que HTML , HAL Forms , halform , ion ou Hydra . Je suis actuellement, cependant, pas au courant d'un type de média qui peut automatiquement coder les données d'entrée en
text/csv
directement où on pourrait avoir besoin d'être défini et enregistré avec le registre de type de support de l' IANA .Le téléchargement et le téléchargement du jeu de paramètres complet ne devraient pas être un problème, je suppose. Comme mentionné précédemment, l'URI cible n'est pas pertinent car un client utilisera simplement l'URI pour récupérer le nouveau contenu à traiter. Le filtrage par date ouvrable ne devrait pas non plus être trop difficile. Ici, le serveur doit cependant le client avec toutes les possibilités que le client peut simplement choisir. Ces dernières années, GraphQL et RestQL ont évolué, introduisant un langage de type SQL qui peut être ciblé sur un certain point de terminaison pour obtenir une réponse filtrée. Cependant, dans un vrai sens REST, cela viole l'idée derrière REST comme a) GraphQL c'est-à-dire n'utilise qu'un seul point de terminaison qui empêche en quelque sorte l'utilisation optimale de la mise en cache et b) nécessite la connaissance des champs disponibles à l'avance, ce qui peut conduire à introduire un couplage de clients au modèle de données de base de la ressource.
L'activation ou la désactivation de certains paramètres de configuration est simplement une question de déclenchement des contrôles hypermédia qui offrent cette possibilité. Dans les formulaires HTML, cela peut être une simple case à cocher ou une sélection sur plusieurs lignes dans une liste ou ce genre. Selon le formulaire et la méthode qu'il définit, il pourrait alors potentiellement envoyer la configuration entière via
PUT
ou être intelligent sur les modifications effectuées et effectuer uniquement une mise à jour partielle viaPATCH
. Ce dernier nécessite essentiellement un calcul de la représentation de changement à celle mise à jour et alimente le serveur avec les étapes requises pour transformer la représentation actuelle en celle souhaitée. Selon la spécification PATH, cela doit être fait dans une transaction afin que toutes ou aucune des étapes ne soient appliquées.HTTP autorise et encourage un serveur à valider une demande reçue à l'avance avant d'appliquer les modifications. Pour PUT, la spécification stipule:
Pour résumer ce message, vous devez soit utiliser un type de support existant qui vous permet d'enseigner à un client les paramètres d'entrée requis ou pris en charge, l'emplacement cible auquel envoyer la demande, l'opération à utiliser ainsi que le type de support le La demande doit être formatée ou définir la vôtre que vous enregistrez auprès de l'IANA. Ce dernier peut être nécessaire si vous souhaitez convertir l'entrée en
text/csv
puis téléchargez la représentation CSV sur le serveur. La validation doit avoir lieu avant que les modifications ne soient appliquées à la ressource. L'URI réel ne doit pas être pertinent pour les clients autrement que pour déterminer où envoyer la demande et, en tant que tel, peut être librement choisi par vous, le prestataire de services. En suivant ces étapes, vous avez à peu près la liberté de changer votre côté serveur à tout moment et les clients ne se casseront pas en conséquence s'ils prennent en charge les types de supports utilisés.la source
Edit: En effet, l'URI aurait empêché les
GET
demandes de rester idempotentes.Cependant, pour la validation, l'utilisation de codes d'état HTTP pour notifier la validité d'une demande (pour créer un nouveau ou modifier un «paramètre» existant) conviendrait à un modèle Restful.
Signaler un
400 Bad Request
code d'état si les données soumises sont / ne sont pas valides et la demande doit être modifiée avant d'être soumise à nouveau ( codes d'état HTTP / 1.1 ).Cela dépend cependant de la validation au moment de la soumission, plutôt que de la différer comme dans votre cas d'utilisation. Les autres réponses ont des solutions adaptées à ce scénario.
la source
Dans un environnement REST, chaque URL est une ressource unique. Quelles sont vos ressources? Une calculatrice financière n'a vraiment pas de ressources évidentes. Vous devez creuser dans ce que vous appelez des paramètres et retirer les ressources. Par exemple, un calendrier d'amortissement pour un prêt peut être une ressource. L'URL du calendrier peut inclure la date de début, la durée (en mois ou en années), la période (lorsque les intérêts sont composés), le taux d'intérêt et le principe initial. Avec toutes ces valeurs, vous avez un calendrier de paiements spécifique:
Maintenant, je ne sais pas ce que vous calculez, mais votre concept de liste de paramètres ne semble pas RESTful. Comme quelqu'un l'a dit, vos exigences ci-dessus sonnent plus comme XMLRPC. Si vous essayez pour REST, vous avez besoin de noms. Les calculs ne sont pas des noms, ce sont des verbes qui agissent sur des noms. Vous devez le retourner pour retirer les noms de vos calculs.
la source