Comment créer des URL REST sans verbes?

283

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:

  1. Télécharger de nouveaux paramètres
  2. Obtenez les derniers paramètres
  3. Obtenir des paramètres pour une date commerciale donnée
  4. Rendre un ensemble de paramètres actif
  5. 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:

  1. POST où vous incluez le fichier de paramètres dans la demande de publication
  2. OBTENIR la première URL
  3. 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

??

Marcus Leon
la source
3
Je préfère PATCH plutôt que POST pour une mise à jour partielle.
user2016971

Réponses:

71

Peut-être quelque chose comme:

PUT /parameters/activation HTTP/1.1
Content-Type: application/json; encoding=UTF-8
Content-Length: 18

{ "active": true }
yfeldblum
la source
1
POSTest 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.
Andrey Vlasovskikh
19
PUT sert à créer une nouvelle ressource, ou à placer (en totalité, pas en partie) une nouvelle ressource à une URL particulière. Je ne vois pas comment PUT s'intègre dans ce cas.
Breton
30
En fait, POSTvs PUTn'est pas exactement comme insertvs update. PUTmet à jour la ressource correspondant au chemin donné ou crée une nouvelle ressource correspondant au chemin donné. POSTcrée une nouvelle ressource quelque part. Par exemple, PUT /blog/posts/3/comments/5mettra à jour le commentaire approprié, tandis que POST /blog/posts/3/commentscréera une nouvelle commentressource (et devrait retourner le chemin d'accès à la nouvelle ressource dans la réponse).
yfeldblum
23
@Justice @Breton La différence la plus importante est qu'elle PUTest idempotente alors qu'elle POSTne l'est pas. Habituellement, vous devez mettre autant de contraintes que possible sur ce que vous fournissez. Rester avec PUTdonne plus d'informations au client du service.
Andrey Vlasovskikh
3
La ressource pourrait également avoir été / parameters / status et le corps de la demande aurait pu être simplement "actif". De cette façon, vous placez en quelque sorte une toute nouvelle ressource dans une URL particulière.
Carlos Aguayo
991

Principes généraux pour une bonne conception d'URI:

  • N'utilisez pas les paramètres de requête pour modifier l'état
  • N'utilisez pas de chemins à casse mixte si vous pouvez l'aider; les minuscules sont les meilleures
  • N'utilisez pas d' extensions spécifiques à l'implémentation dans vos URI (.php, .py, .pl, etc.)
  • Ne tombez pas dans RPC avec vos URI
  • Ne limitez votre espace URI autant que possible
  • Do segments de chemin de court donjon
  • Do préfèrent soit /resourceou /resource/; créer 301 redirections à partir de celle que vous n'utilisez pas
  • Ne utiliser des paramètres de requête pour sous-sélection d'une ressource; c'est-à-dire la pagination, les requêtes de recherche
  • Faites déplacer des choses de l'URI qui devrait être dans un en- tête HTTP ou un corps

(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:

  • N'utilisez jamais GET pour modifier l'état; c'est un excellent moyen d'avoir le Googlebot gâcher votre journée
  • N'utilisez PUT que si vous mettez à jour une ressource entière
  • N'utilisez PUT que si vous pouvez également légitimement faire un GET sur le même URI
  • N'utilisez pas POST pour récupérer des informations de longue durée ou qui pourraient être raisonnables à mettre en cache
  • Ne pas effectuer une opération qui n'est pas idempotente avec PUT
  • Faites usage GET pour autant que possible
  • Faites usage POST de préférence à PUT en cas de doute
  • Faites usage POST chaque fois que vous devez faire quelque chose qui se sent comme RPC
  • Faire usage PUT pour les classes de ressources qui sont plus grandes ou hiérarchique
  • Ne utilisez la commande DELETE de préférence à POST aux ressources remove
  • Do utiliser GET pour des choses comme les calculs, à moins que votre entrée est grande, dans ce cas , utilisez POST

Principes généraux de la conception de services Web avec HTTP:

  • Ne mettez pas de métadonnées dans le corps d'une réponse qui devrait être dans un en-tête
  • Ne placez pas les métadonnées dans une ressource distincte, sauf si leur inclusion entraînerait une surcharge importante
  • N'utiliser le code d'état approprié
    • 201 Createdaprès avoir créé une ressource; la ressource doit exister au moment de l'envoi de la réponse
    • 202 Accepted après avoir effectué une opération avec succès ou créé une ressource de manière asynchrone
    • 400 Bad Requestquand 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ées
    • 401 Unauthorizedlorsque quelqu'un accède à votre API sans fournir un en- Authorizationtête nécessaire ou lorsque les informations d'identification dans le Authorizationsont invalides; n'utilisez pas ce code de réponse si vous n'attendez pas d'informations d'identification via un en- Authorizationtê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 volumineux
    • 418 I'm a teapot lorsque vous essayez de préparer du café avec une théière
  • Utilisez des en-têtes de mise en cache chaque fois que vous le pouvez
    • ETag les en-têtes sont bons lorsque vous pouvez facilement réduire une ressource à une valeur de hachage
    • Last-Modified devrait vous indiquer que le respect d'un horodatage de la mise à jour des ressources est une bonne idée
    • Cache-Controlet Expiresdevrait recevoir des valeurs sensibles
  • Faites tout ce que vous pouvez pour honorer les en-têtes de mise en cache dans une demande ( If-None-Modified, If-Modified-Since)
  • Utilisez des redirections quand elles ont du sens, mais elles devraient être rares pour un service Web

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.

Bob Aman
la source
11
413 est conçu pour la taille de la demande qui vous est envoyée afin que vous puissiez rejeter poliment quelqu'un qui vous envoie des données, souvent en conjonction avec 411 afin de forcer les gens à vous dire combien est envoyé. Pour l'exemple donné contre 413, je pense que 400 serait une réponse plus appropriée.
Garry Shutler
5
+1 car c'est une excellente ressource. Cependant, c'est une ressource générale et ne répond pas directement à la question. Idéalement, cela devrait inclure un paragraphe supplémentaire avec une réponse spécifique.
Samuel Neff
@GarryShutler Bonne prise, vous avez absolument raison. Merci pour l'édition.
Bob Aman
1
Oui, vous n'utiliseriez PUT que dans les cas où vous écrasez l'objet entier. Cependant, je dirais que PATCH ou POST sont raisonnables dans le cas d'une mise à jour partielle d'une ressource. PATCH est plus clair en termes de ce que l'opération va faire, mais comme tous les clients ne sont même pas capables d'émettre une demande PATCH , il est tout à fait approprié d'autoriser un POST à ​​la place, et je pourrais même aller jusqu'à préconiser qu'un POST doit toujours être autorisé comme solution de rechange si PATCH est utilisé.
Bob Aman
1
+1 pour 409 erreurs. Une erreur 400 est quelque chose qui pourrait être résolu par une validation côté client suffisante. Un 409 précise que la demande elle-même était acceptable et cohérente, mais entre en conflit avec certains aspects de l'état du serveur (généralement les contrôles de concurrence, mais théoriquement toute contrainte de non-entrée).
claytond
18

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 .

Rich Apodaca
la source
1
C'est un très bon point. Il est facile de manquer si vous êtes dans l'état d'esprit pour traiter la logique formelle et le raisonnement. Peu importe ce qu'est X tant qu'il s'accorde avec les autres parties de manière valide. Les facteurs humains disparaissent.
Breton
1
Parfois, je trouve utile de convertir les mots en une "ressource de traitement" comme "activateur" ou "validateur". Selon RFC 2616, le POST peut être utilisé pour "fournir un bloc de données ... à un processus de traitement des données"
Darrel Miller
Compris. Dans ce cas, les utilisateurs appellent les données "paramètres" (ou "paramètres de risque" ou quelque chose de similaire). La liste des paramètres contient de nombreux types de paramètres différents, mais les paramètres sont toujours téléchargés dans leur ensemble (dans un fichier CSV).
Marcus Leon
@Marcus - cela ressemble à un cas très inhabituel. Peut-être que si vous expliquiez plus en détail ce que fait votre application, nous serions en mesure de proposer de meilleures suggestions pour identifier les ressources.
Rich Apodaca
1
"Lorsque vous discutez de votre application avec les utilisateurs finaux, quels sont les mots qu'ils utilisent eux-mêmes à plusieurs reprises?" ... et si ce sont tous des verbes? XD
Amalgovinus
11

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:

GET [parametersurl]/validationresults

POST [paramatersurl]
body: {command:"activate"}

Mais encore une fois, cette chose d'activation est RPC, pas REST.

Breton
la source
Vous énoncez un point intéressant ici. Pouvez-vous nous expliquer un peu plus comment serait l'approche RESTful pour quelque chose comme ça?
poezn
J'ai passé un peu de temps à lire les réponses ici, et je pense que la justice pourrait être sur quelque chose. il modélise les propriétés individuelles de votre objet paramètres en tant que ressources individuelles et utilise le verbe PUT pour remplacer le contenu de cette propriété sur cette ressource. Il s'agit de modéliser l'état de chaque objet en tant que collection de ressources et de modifier l'état en plaçant, supprimant ou modifiant la ressource. Quant à la validation - Vous avez juste besoin d'une ressource qui indique comme par magie si les paramètres sont valides ou non, comme ci-dessus dans ma réponse. Ce serait bien, tant que cela n'a pas d'effets secondaires.
Breton
Pourvu bien sûr que ce que fait "Activer" soit simplement mettre une propriété unique à true. S'il doit faire autre chose, ce n'est toujours pas RESTful, et je ne sais pas comment vous le modéliserez RESTful.
breton
Je ne pense pas que vous puissiez dire que les deux derniers cas ne sont pas reposants. En effet, Activer et Valider ne sont que des moyens indirects de dire que la ressource passe à un nouvel état dans une machine d'état. REST est tout à fait capable de modéliser cela.
Darrel Miller
@Darrel, je pense que vous signalez une partie de REST qui peut être difficile pour de nombreuses personnes qui découvrent REST. Comment pouvez-vous procéder pour implémenter une opération "Valider la ressource x"? Je pense que la difficulté est qu'il s'agit d'une opération qui pourrait entraîner un changement d'état, mais le nouvel état est le résultat de la demande.
Sean
6

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,

/ActiveParameters
/ValidatedParameters

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:

POST /ActiveParameters?parameter=/Parameters/{Id}

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.

Darrel Miller
la source
1

Je suggère la ressource et les méthodes Meta suivantes.

Activez et / ou validez les paramètres:

> PUT /parameters/<id>/meta HTTP/1.1
> Host: example.com
> Content-Type: application/json
> Connection: close
>
> {'active': true, 'require-valid': true}
>
< HTTP/1.1 200 OK
< Connection: close
<

Vérifiez si les paramètres sont actifs et valides:

> GET /parameters/<id>/meta HTTP/1.1
> Host: example.com
> Connection: close
>
< HTTP/1.1 200 OK
< Content-Type: application/json
< Connection: close
<
< {
<     'active': true,
<     'require-valid': true,
<     'valid': {'status': false, 'reason': '...'}
< }
<
Andrey Vlasovskikh
la source
Pour autant que je comprends, la question porte sur la dénomination des URL reposantes, pas sur la fonctionnalité, n'est-ce pas?
poezn
2
Une question limitée aux "URL RESTful" est une mauvaise question et ne doit pas recevoir de réponse. Au lieu de cela, la question devrait être développée pour prendre en compte les "ressources RESTful, avec les méthodes et URL associées" - et y répondre comme telle.
yfeldblum
Si j'ai bien compris, la question portait sur les conventions de dénomination des URL et les méthodes HTTP auxquelles la ressource nommée devrait répondre.
Andrey Vlasovskikh
1

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 deapplication/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:

<html>
  <head>
    ...
  </head>
  <body>
    <form action="/../someResource" method="post" enctype="application/x-www-form-urlencoded">
      <label for="firstNumber">First number:</label>
      <input type="number" id="firstNumber" name="firstNumber"/>

      <label for="secondNumber">Second number:</label>
      <input type="number" id="secondNumber" name="secondNumber"/>

      <input type="submit" value="Add numbers"/>
    </form>
  </body>
</html>

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-urlencodedformat de représentation qui est envoyé à l'emplacement cible mentionné via la méthode de requête HTTP spécifiée, POSTdans ce cas. Si nous entrons 1dans le firstNumberchamp de saisie et 2dans le secondNumberchamp de saisie, le navigateur va générer une représentation firstNumber=1&secondNumber=2et 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:

POST /../someResource
Host: www.acme.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 28
Accept: application/html

firstNumber=1&secondNumber=2

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 preloaddes 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-urlencodedrepré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 prendre text/csven 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/csvdirectement 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 PUTou être intelligent sur les modifications effectuées et effectuer uniquement une mise à jour partielle via PATCH. 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:

Un serveur d'origine DEVRAIT vérifier que la représentation PUT est cohérente avec toutes les contraintes du serveur pour la ressource cible qui ne peuvent pas ou ne seront pas modifiées par le PUT. Ceci est particulièrement important lorsque le serveur d'origine utilise des informations de configuration internes liées à l'URI afin de définir les valeurs des métadonnées de représentation sur les réponses GET. Lorsqu'une représentation PUT n'est pas cohérente avec la ressource cible, le serveur d'origine DEVRAIT soit les rendre cohérentes, en transformant la représentation ou en modifiant la configuration de la ressource, soit répondre avec un message d'erreur approprié contenant des informations suffisantes pour expliquer pourquoi la représentation est inadaptée. Les codes d'état 409 (Conflit) ou 415 (Type de support non pris en charge) sont suggérés,

Par exemple, si la ressource cible est configurée pour toujours avoir un Content-Type de "text / html" et que la représentation en cours PUT a un Content-Type de "image / jpeg", le serveur d'origine doit faire l'une des actions suivantes:

une. reconfigurer la ressource cible pour refléter le nouveau type de média;

b. transformer la représentation PUT en un format cohérent avec celui de la ressource avant de l'enregistrer en tant que nouvel état de ressource; ou,

c. rejeter la demande avec une réponse 415 (type de support non pris en charge) indiquant que la ressource cible est limitée à "text / html", y compris peut-être un lien vers une ressource différente qui serait une cible appropriée pour la nouvelle représentation.

HTTP ne définit pas exactement comment une méthode PUT affecte l'état d'un serveur d'origine au-delà de ce qui peut être exprimé par l'intention de la demande de l'agent utilisateur et la sémantique de la réponse du serveur d'origine. ...

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 entext/csvpuis 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.

Roman Vottner
la source
0

Edit: En effet, l'URI aurait empêché les GETdemandes 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 Requestcode 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.

Derek Mortimer
la source
L'URI est censé être un identifiant. L'utilisation d'une URL particulière ne devrait pas avoir d'effets secondaires. Imaginez ce qu'un proxy ferait avec ça.
Breton
2
ou google, d'ailleurs. J'ai lu une fois une histoire sur une boutique en ligne qui avait tous ses produits supprimés par google à cause de ce genre d'idiotie.
Breton
0

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:

http://example.com/amort_cal/2009-10-20/30yrsfixed/monthly/5.00/200000

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.

jmucchiello
la source
5
Je pense que c'est un peu idiot d'utiliser des barres obliques ici, quel serait le problème avec amort_cal? Date = 2009-10-20 & type = 30yrsfixed & period = mensuel & rate = 5.0 & initialamount = 200000? REST s'en fiche tant qu'il s'agit d'une ressource. La spécification URI fait cependant attention. Comment imaginez-vous des liens relatifs pour travailler avec un schéma comme celui-ci?
Breton
Vous soulevez néanmoins un bon point. Ces "paramètres" doivent-ils même être stockés côté serveur? Si ce n'est qu'un calcul ponctuel, pourquoi ne pas simplement créer un espace virtuel, où les paramètres sont dans l'URL. Tant que vous ne changez pas l'état interne, ça devrait aller.
Breton
1
Et les "paramètres" ne s'appliquent pas à une "ressource". Une ressource est une entité unique avec un identifiant unique. Mon URL identifie une seule ressource. Une URL paramétrée indique une collection de ressources que vous sélectionnez parmi l'utilisation des paramètres.
jmucchiello
2
REST n'est pas basé sur "CRUDing Resources". Coller tous vos paramètres de requête dans des segments de chemin ne crée pas automatiquement une interface RESTful, car vous pensez maintenant que vous pouvez appeler chaque permutation une ressource. Malheureusement, il n'y a pas de processus magique que vous pouvez appliquer pour identifier les ressources de votre système. Il nécessite une conception soignée, pas une formule mécanique.
Darrel Miller,
2
Encore une fois, l'architecture REST ne se soucie pas du contenu de l'URL. l'URL est censée être opaque . Peu importe que vous utilisiez des barres obliques, des points-virgules ou des cœurs unicode comme séparateurs. Lisez ceci et répondez à cela - pas à ce que vous imaginez que je dis.
Breton