Comment les recherches s'intègrent-elles dans une interface RESTful?


137

Lors de la conception d'une interface RESTful, la sémantique des types de demandes est considérée comme essentielle à la conception.

  • GET - Lister une collection ou récupérer un élément
  • PUT - Remplace la collection ou l'élément
  • POST - Créer une collection ou un élément
  • DELETE - Eh bien, erm, delete collection ou element

Cependant, cela ne semble pas couvrir le concept de "recherche".

Par exemple, lors de la conception d'une suite de services Web prenant en charge un site de recherche d'emploi, les conditions suivantes peuvent être remplies:

  • Obtenir une offre d'emploi individuelle
    • Se rendre àdomain/Job/{id}/
  • Créer une offre d'emploi
    • POST àdomain/Job/
  • Mettre à jour une offre d'emploi
    • PUT àdomain/Job/
  • Supprimer une offre d'emploi
    • SUPPRIMER àdomain/Job/

"Get All Jobs" est aussi simple:

  • Se rendre àdomain/Jobs/

Cependant, comment la "recherche" d'emploi entre-t-elle dans cette structure?

Vous pouvez prétendre que c'est une variante de "list collection" et implémenter comme:

  • Se rendre àdomain/Jobs/

Cependant, les recherches peuvent être complexes et il est tout à fait possible de générer une recherche générant une longue chaîne GET. En d’autres termes, si l’on fait référence à une question SO , il existe des problèmes liés à l’utilisation de chaînes GET plus longues que 2 000 caractères environ.

Un exemple pourrait être dans une recherche à facettes - en continuant l’exemple "job".

Je peux autoriser la recherche sur des facettes - "Technologie", "Titre du travail", "Discipline" ainsi que sur les mots-clés en texte libre, l'âge du travail, l'emplacement et le salaire.

Avec une interface utilisateur fluide et un grand nombre de technologies et de titres d'emploi, il est possible qu'une recherche englobe un grand nombre de choix de facettes.

Ajustez cet exemple en CV, plutôt qu'en emplois, apportez encore plus de facettes, et vous pouvez très facilement imaginer une recherche avec une centaine de facettes sélectionnées, ou même seulement 40 facettes de 50 caractères chacune (par exemple, Titres de poste, Noms d'université, Noms d’employeurs).

Dans cette situation, il peut être souhaitable de déplacer un PUT ou un POST afin de s’assurer que les données de recherche seront correctement envoyées. Par exemple:

  • POST àdomain/Jobs/

Mais sémantiquement, c'est une instruction pour créer une collection.

Vous pouvez également dire que vous exprimerez ceci sous la forme d'une recherche:

  • POST àdomain/Jobs/Search/

ou (comme suggéré par burninggramma ci-dessous)

  • POST àdomain/JobSearch/

Sémantiquement, cela peut sembler logique, mais vous ne créez rien, vous faites une demande de données.

Donc, sémantiquement, c'est un GET , mais GET n'est pas garanti pour prendre en charge ce dont vous avez besoin.

La question est donc la suivante: essayer de rester aussi fidèle que possible à la conception RESTful tout en veillant à rester dans les limites du protocole HTTP, quelle est la conception la plus appropriée pour une recherche?


3
J'ai souvent l'intention d'utiliser GET domain/Jobs?keyword={keyword} . Cela fonctionne très bien pour moi :) J'espère que le SEARCHverbe deviendra un standard. programmers.stackexchange.com/questions/233158/…
Knerd

Oui, je peux voir que pour un exemple trivial, il n'y a pas de problème. Mais dans l'outil que nous construisons, il n'est en fait pas si incroyable que nous aboutissions à une recherche complexe aboutissant à une chaîne GET de plus de 2 000 caractères. Quoi alors?
Rob Baillie

En fait un très bon point. Qu'en est-il de spécifier une technologie de compression?
Knerd

2
GET avec un corps est autorisé par la spécification HTTP, peut être ou non pris en charge par un middleware (parfois non);) et n'est pas privilégié en tant que pratique. Cela arrive périodiquement sur Stackexchange. stackoverflow.com/questions/978061/http-get-with-request-body
Rob

2
J'ai finalement demandé à POST JobSearch de créer une entité de recherche réelle et de renvoyer un jobSearchId. Puis GET jobs? JobSearch = jobSearchId renvoie la collection de travaux actuelle.
Cerad

Réponses:


93

N'oubliez pas que les demandes GET présentent des avantages supérieurs à ceux des autres solutions:

1) Les requêtes GET peuvent être copiées à partir de la barre d’URL, elles sont digérées par les moteurs de recherche, elles sont "conviviales". Où "amical" signifie que normalement une requête GET ne doit rien modifier à l'intérieur de votre application (idempotent) . C'est le cas standard pour une recherche.

2) Tous ces concepts sont très importants, non seulement du point de vue de l'utilisateur et du moteur de recherche, mais aussi du point de vue architectural, de la conception d'API .

3) Si vous créez une solution de contournement avec POST / PUT, vous aurez des problèmes auxquels vous ne pensez pas pour le moment. Par exemple, dans le cas d'un navigateur, le bouton de navigation précédente / actualiser la page / l'historique. Celles-ci peuvent être résolues bien sûr, mais cela va être une autre solution de contournement, puis une autre et une autre ...

Compte tenu de tout cela, mon conseil serait:

a) Vous devriez pouvoir vous adapter à votre GET en utilisant une structure de paramètres intelligente . Dans les cas extrêmes, vous pouvez même opter pour des tactiques telles que cette recherche google dans laquelle je règle beaucoup de paramètres, mais c’est toujours une URL très courte.

b) Créez une autre entité dans votre application, telle que JobSearch . En supposant que vous ayez tellement d'options, il est probable que vous ayez également besoin de stocker ces recherches et de les gérer. Il vous suffit donc de clarifier votre application. Vous pouvez utiliser les objets JobSearch comme une entité complète, ce qui signifie que vous pouvez le tester / l’utiliser plus facilement .


Personnellement, j'essayerais de me battre avec toutes mes griffes pour le faire avec a) et lorsque tout espoir serait perdu, je ramperais avec les larmes aux yeux vers l'option b) .


4
Pour plus de clarté, cette question est destinée à la conception de services Web, pas à la conception de sites Web. Ainsi, alors que le comportement du navigateur présente un intérêt pour la portée plus large de l'interprétation de la question, dans le cas particulier décrit, cela n'a aucune conséquence. (point intéressant cependant).
Rob Baillie

@RobBaillie Le navigateur n'était qu'un cas d'utilisation. Je voulais exprimer le fait que votre recherche dans son ensemble est représentée par une chaîne d'URL. Ce qui a beaucoup de confort dans la convivialité avec d'autres points plus tard dans la réponse.
p1100i

Point b, est - ce une simple variante de ma propre référence à un POST à domain/Jobs/Search/, peut - être avec la domain/JobsSearch/place, ou avez - vous dire quelque chose de différent? Pouvez-vous clarifier?
Rob Baillie

7
Pourquoi ai-je l'impression que REST fait souvent partie du problème plutôt que de la solution?
JensG

1
"La requête GET ne doit rien modifier à l'intérieur de votre application (idempotent)" alors que GET est idempotent, le mot pertinent est " sûr " ici. Idempotent signifie qu'effectuer une opération GET deux fois est la même chose qu'une opération GET une fois. PUT est également idempotent, mais pas sûr, par exemple.
Jasmijn

12

TL; DR: GET pour le filtrage, POST pour la recherche

Je fais une distinction entre filtrer les résultats de la liste d'une collection par rapport à une recherche complexe. Le test décisif que j'utilise est essentiellement si j'ai besoin de plus que du filtrage (positif, négatif ou plage). Je considère qu'il s'agit d'une recherche plus complexe nécessitant un test POST.

Cela tend à être renforcé lorsque l’on réfléchit à ce qui sera retourné. J'utilise généralement uniquement GET si une ressource a un cycle de vie essentiellement complet (PUT, DELETE, GET, collection GET) . Généralement, dans une collection GET, je retourne une liste d'URI qui sont les ressources REST qui composent cette collection. Dans une requête complexe, il est possible que je tire plusieurs ressources afin de construire la réponse (pensez à une jointure SQL) afin que je ne renvoie pas d'URI, mais des données réelles. Le problème est que les données ne seront pas représentées dans une ressource, je devrai donc toujours renvoyer des données. Cela me semble être un cas clair d’exiger un POST.

-

Cela faisait longtemps et mon message original était un peu bâclé, alors j'ai pensé mettre à jour.

GET est le choix intuitif pour renvoyer la plupart des types de données, des collections de ressources REST, des données structurées d'une ressource, même des charges utiles uniques (images, documents, etc.).

POST est la méthode la plus répandue pour tout ce qui ne semble pas correspondre à GET, PUT, DELETE, etc.

À ce stade, je pense que les recherches simples et le filtrage ont un sens intuitif grâce à GET. Les recherches complexes dépendent de vos préférences personnelles, en particulier si vous ajoutez des fonctions d’agrégation, des corrélations croisées (jointures), des reformatages, etc. ) peut souvent avoir plus de sens en tant que corps de requête POST.

Je considère également l'aspect expérience de l'utilisation de l'API. Je souhaite généralement que la plupart des méthodes soient aussi simples à utiliser et intuitives que possible. J'appliquerai les appels plus flexibles (et donc plus complexes) dans des POST et vers un autre URI de ressource, en particulier s'il est incompatible avec le comportement d'autres ressources REST de la même API.

Dans les deux cas, la cohérence est probablement plus importante que la recherche dans GET ou POST.

J'espère que cela t'aides.


1
Étant donné que REST est destiné à extraire l’implémentation sous-jacente (par exemple, une ressource n’est pas nécessairement une ligne dans une base de données ou un fichier sur un disque dur, mais peut être n'importe quoi ). Je ne sais pas pourquoi il est logique d’utiliser POST sur GET pour effectuer des jointures SQL. Supposons que vous ayez une table d'écoles et une table d'enfants et que vous souhaitiez une classe (une école, plusieurs enfants). Vous pouvez facilement définir une ressource virtuelle et GET /class?queryParams. Du point de vue d'un utilisateur, la "classe" a toujours été une chose et vous n'avez pas à faire de jointures SQL bizarres.
stevendesu

Il n'y a pas de différence entre "filtrage" et "recherche".
Nicholas Shanks

1
Oui, un filtre est basé sur les champs existants. Une recherche peut contenir des modèles beaucoup plus complexes, combinant des champs, calculant des valeurs
adjacentes,

@stevendesu exactement, c'est pourquoi j'utilise POST pour les deux (création d'une recherche) :-)
ymajoros

@ymajoros Sauf si vous enregistrez les termes de recherche et les résultats de la recherche quelque part, je ne sais pas si POST a un sens sur le plan sémantique. Lorsque vous effectuez une recherche, vous effectuez une demande d'informations, vous ne fournissez aucune nouvelle information à conserver nulle part.
vendredi

10

Dans REST, la définition des ressources est très large. Cependant, vous souhaitez vraiment regrouper certaines données.

  • Il est utile de penser à une ressource de recherche en tant que ressource de collection. Les paramètres de requête, parfois appelés partie interrogeable de l'URI, limitent la ressource aux éléments qui intéressent le client.

Par exemple, l'URI principal de Google pointe vers une ressource de collection composée de "liens vers tous les sites Internet". Les paramètres de requête limitent cela aux sites que vous voulez voir.

(URI = identifiant de ressource universel, dont URL = localisateur de ressources universel, où le "http: //" bien connu est le format par défaut d'un URI. Donc, URL est un localisateur, mais dans REST, il est bon de généraliser à un identificateur de ressource. Les gens les utilisent de manière interchangeable, cependant.)

  • Étant donné que la ressource que vous recherchez dans votre exemple est la collection d’emplois, il est logique de rechercher avec

GET site / jobs? Type = blah & location = ici & etc = etc

(retourne) {jobs: [{job: ...}]}

Et utilisez ensuite POST, qui est le verbe append ou process pour ajouter de nouveaux éléments à cette collection:

POST site / emplois

{emploi: ...}

  • Notez que c'est la même structure pour l' jobobjet dans chaque cas. Un client peut obtenir une collection de travaux en utilisant des paramètres de requête pour affiner la recherche, puis utiliser le même format pour l'un des éléments afin de publier un nouveau travail. Ou il peut prendre l'un de ces éléments et PUT à son adresse URI pour mettre à jour celui-ci.

  • Pour les chaînes de requête très longues ou compliquées, la convention permet d’envoyer celles-ci sous forme de requêtes POST. Regroupez les paramètres de la requête sous forme de paires nom / valeur ou d'objets imbriqués dans une structure JSON ou XML et envoyez-les dans le corps de la requête. Par exemple, si votre requête contient des données imbriquées au lieu de plusieurs paires nom / valeur. La spécification HTTP pour POST le décrit comme le verbe append ou process. (Si vous voulez naviguer dans un cuirassé à travers une échappatoire dans REST, utilisez POST.)

J'utiliserais cela comme plan de secours, cependant.

Ce que vous perdez quand vous faites cela, c’est que a) GET est nullipotent - c’est-à-dire que cela ne change rien - POST ne l’est pas. Donc, si l'appel échoue, le middleware ne réessayera pas automatiquement ni ne mettra en cache les résultats. 2) avec les paramètres de recherche dans le corps, vous ne pourrez plus couper et coller l'URI. En d'autres termes, l'URI n'est pas un identifiant spécifique pour la recherche que vous souhaitez.

Faire la distinction entre "créer" et "rechercher". Quelques options sont compatibles avec la pratique REST:

  • Vous pouvez le faire dans l'URI en ajoutant quelque chose au nom de la collection, par exemple recherche d'emploi au lieu d'emplois. Cela signifie simplement que vous traitez la collection de recherche comme une ressource distincte.

  • La sémantique de POST étant à la fois un processus append OR, vous pouvez identifier les corps de recherche avec la charge utile. Comme {job: ...} vs {search: ...}. C'est à la logique du POST de le poster ou de le traiter correctement.

C'est à peu près une préférence de conception / mise en œuvre. Je ne pense pas qu'il y ait une convention claire.

Donc, comme vous l’avez déjà expliqué, l’idée est de définir une ressource de collection pour jobs

site / emplois

Effectuez une recherche avec les paramètres de requête GET + pour affiner la recherche. Les requêtes de données longues ou structurées vont dans le corps d'un POST (éventuellement dans une collection de recherche séparée). Créez avec POST pour ajouter à la collection. Et mettre à jour avec PUT vers un URI spécifique.

(FWIW, la convention de style avec les URI consiste à utiliser tous les caractères minuscules avec des mots séparés par des traits d'union. Mais cela ne signifie pas que vous devez le faire de cette façon.)

(En outre, je dois dire que, d'après votre question, il est clair que vous êtes sur une longue route. J'ai expliqué les choses de manière explicite simplement pour les aligner, mais votre question avait déjà abordé la plupart des problèmes sémantiques dans ce Je répondais juste avec une convention et une pratique)


C'est une idée intéressante - je n'aurais pas envisagé d'utiliser la charge utile pour faire la différence. Cela semble presque un peu sournois! Mais je suppose que le schéma d'URI ne contient en réalité aucun verbe - c'est le type de requête qui définit le verbe. Peut-être que la charge utile est plus sémantiquement plus proche du type de demande que l'URI. La seule préoccupation est la suivante: est-ce transparent pour un utilisateur de l'API?
Rob Baillie

En termes de mise en œuvre (nous utilisons Node et Express), cela peut signifier qu’ils routene peuvent pas vraiment gérer le choix du traitement. Je devrais jeter un oeil à ça ...
Rob Baillie

J'ai le même sentiment que de le séparer par URI semble plus propre. Je suis en quelque sorte aller et venir; c'est un jugement. Cependant, la sémantique de HTTP permettrait de le mettre dans le corps. J'aime dire que REST est calqué sur le World Wide Web et que le WWW a été créé avec GET et POST.
Rob

8

J'utilise généralement les requêtes OData, elles fonctionnent en tant qu'appel GET mais vous permettent de restreindre les propriétés renvoyées et de les filtrer.

Vous utilisez des jetons tels que $select=et $filter=vous obtiendrez ainsi un URI ressemblant à ceci:

/users?$select=Id,Name$filter=endswith(Name, 'Smith')

Vous pouvez également faire en utilisant la pagination $skipet $topet la commande.

Pour plus d'informations, consultez OData.org . Vous n'avez pas spécifié la langue que vous utilisez, mais s'il s'agit d'ASP.NET, la plate-forme WebApi prend en charge les requêtes OData. Pour d'autres (PHP, etc.), il existe probablement des bibliothèques que vous pouvez utiliser pour les traduire en requêtes de base de données.


6
Un lien intéressant et intéressant de regarder, mais faut - il résoudre le problème fondamental décrit, que les requêtes GET ne prennent pas en charge plus de 2000 caractères dans la chaîne de requête, et il est tout à fait possible que la requête pourrait être beaucoup plus que cela?
Rob Baillie

@RobBaillie Je ne pense pas, car il s'agit toujours d'un appel GET avec une chaîne de requête. Je suggérerais d'utiliser OData chaque fois que vous le pouvez, car il s'agit d'un standard pour l'interrogation de sources de données Web et, dans les rares cas (le cas échéant), la requête doit être si complexe que vous ne pouvez pas l'adapter à une requête de 2 000 caractères. point final auquel vous passez un appel GET
Trevor Pilley

Pouvez-vous expliquer votre approche pour "un point de terminaison spécifique auquel vous appelez GET"? Comment pourriez-vous imaginer ce point final?
Rob Baillie

@RobBaillie bien sûr - encore une fois, je ne suis pas sûr de la technologie que vous utilisez, mais sous ASP.NET, je créerais un contrôleur spécifique appelé JobsNearMeAddedInTheLast7Daysou quoi que ce soit pour encapsuler la requête trop longue / complexe pour OData et l'exposer ensuite uniquement via des appels GET. .
Trevor Pilley

1
Je vois. Une autre idée intéressante qui a probablement des jambes, bien que je ne sois pas sûr que cela puisse aider dans mon cas particulier - la recherche facettes avec beaucoup de types de facettes et beaucoup de valeurs de facettes possibles
Rob Baillie

5

Une approche à considérer consiste à traiter l'ensemble des requêtes possibles comme une ressource de collection, par exemple /jobs/filters.

POSTdemandes à cette ressource, avec les paramètres de la requête dans le corps, va créer une nouvelle ressource soit ou d' identifier un filtre équivalent existant et renvoyer une URL contenant son ID: /jobs/filters/12345.

L'identifiant peut être utilisé dans une requête GET pour l' emploi: /jobs?filter=12345. Les GETrequêtes suivantes sur la ressource de filtre renverront la définition du filtre.

Cette approche présente l'avantage de vous libérer du format de paramètre de requête pour la définition de filtre, ce qui vous donne potentiellement plus de pouvoir pour définir des filtres complexes. Les conditions OU sont un exemple auquel je peux penser qui sont difficiles à accomplir avec des chaînes de requête.

L'inconvénient de cette approche est que vous perdez la lisibilité de l'URL (bien que cela puisse être atténué en récupérant la définition via une GETrequête pour la ressource de filtre). Pour cette raison, vous pouvez également vouloir prendre en charge le même ou un sous-ensemble des paramètres de requête sur la /jobsressource, comme vous le feriez pour une ressource de filtre. Cela pourrait être utilisé pour des requêtes plus courtes. Si cette fonctionnalité est fournie, afin de maintenir la capacité de mise en cache entre les deux types de filtrage, lors de l'utilisation de paramètres de requête sur la /jobsressource, l'implémentation doit créer / réutiliser en interne une ressource de filtrage et renvoyer un 302ou 303statut indiquant l'URL sous la forme /jobs?filter=12345.


Ma première réaction à cela est que, même si c'est une bonne information, il ne s'agit en réalité que d'une variante de la réponse fournie par @burninggramma. Il s’agit essentiellement de "créer une nouvelle entité appelée filtre / recherche, d’appeler pour la créer puis d’appeler pour la récupérer". La variation étant que l'appel pour le récupérer ressemble plus à un appel pour l'appliquer à une collection. Intéressant. Cependant, votre réponse et la réponse de burninggramma souffrent du même problème - je n'ai aucune envie de créer les filtres. Ils seront très nombreux et ils n'ont pas besoin d'être stockés, sauf pour conserver une implémentation RESTful.
Rob Baillie

2
Évidemment, les paramètres de requête sont la meilleure solution, mais votre question porte spécifiquement sur la gestion des définitions de filtre plus longues que la limite imposée aux URL imposée par certains serveurs. Afin de contourner la limite de longueur, vous devez compresser la chaîne de requête ou utiliser une méthode de requête prenant en charge la spécification d'un corps de longueur arbitraire. Si vous ne souhaitez pas traiter les filtres en tant que ressource, prenez en charge une interface non reposante dans laquelle les définitions de filtre sont POSTées. Vous allez perdre la capacité de mise en cache, mais si vos données sont suffisamment volatiles, la mise en cache n'en tirerait aucun avantage.
pgraham

Vous pouvez surmonter le besoin de stocker des filtres simplement ... sans les stocker. Rien sur REST ne garantit sa persistance. Vous pouvez faire une demande GET /jobs/37et recevoir un résultat, puis quelqu'un supprime la ressource et 2 secondes plus tard, la même demande renvoie un 404. De même, si POST /searchesvous êtes redirigé vers un résultat de recherche (la recherche est créée et vous recevez un 201 avec En-tête d’emplacement de la ressource), 2 secondes plus tard, le résultat peut être effacé de la mémoire et doit être régénéré. Pas besoin de stockage à long terme.
Stévendesu

5

C'est une vieille réponse mais je peux toujours contribuer un peu à la discussion. J'ai souvent observé un malentendu entre REST, RESTful et Architecture. RESTful ne mentionne jamais rien de la construction NON recherchée, il n’ya rien dans l’architecture RESTful, c’est un ensemble de principes ou de critères de conception.

Pour mieux décrire une recherche, nous devons parler d'une architecture en particulier et celle qui convient le mieux est l'architecture orientée ressources (ROA).

Dans RESTful, il y a des principes à concevoir, idempotent ne veut pas dire que le résultat ne peut pas changer, comme je l'ai lu dans certaines réponses, cela signifie que le résultat d'une requête indépendante ne dépend pas du nombre d'exécutions exécutées. Cela peut changer, imaginons que je mette à jour continuellement une base de données en lui fournissant des données servies par une API RESTful. L'exécution du même GET peut changer le résultat, mais cela ne dépend pas du nombre de fois qu'elle a été exécutée. Si je suis capable de geler le monde, cela signifie qu'il n'y a pas d'état, de transformation, quoi que ce soit à l'intérieur du service lorsque je demande la ressource qui conduit à un résultat différent.

Par définition, une ressource est tout ce qui est important pour être référencé comme une chose en soi.

Dans une architecture orientée ressources (appelons maintenant ROA par souci de brièveté), nous nous concentrons sur la ressource qui pourrait prendre beaucoup de choses:

  • Une version d'un document
  • La dernière version mise à jour du document
  • Un résultat provenant d'une recherche
  • Une liste d'objets
  • Le premier article que j'ai acheté d'un e-commerce

Ce qui le rend unique en termes de ressources, c'est son adresse, ce qui signifie qu'il n'a qu'un seul URI.

De cette manière, la recherche s’intègre parfaitement dans RESTful en considérant le ROA . Nous devons utiliser GET car je suppose que votre recherche est une recherche normale et qu'elle ne change rien. Elle est donc idempotente (même si elle renvoie des éléments différents en fonction des nouveaux éléments ajoutés). Cela crée une certaine confusion parce que je pourrais m'en tenir à RESTful et non à ROA, cela signifie que je pourrais suivre un modèle qui crée une recherche et renvoie différentes choses avec les mêmes paramètres, car je n'utilise pas le principe d'adressabilité de ROA. Comment c'est? Eh bien, si vous envoyez les filtres de recherche dans le corps ou dans l'en-tête, la ressource n'est pas ADDRESSABLE.

Vous pouvez trouver les principes de quoi exactement et d'URI dans le document original de W3:

https://www.w3.org/DesignIssues/Axioms

Toute URL dans cette architecture doit être auto-descriptive. Il est nécessaire si vous suivez les principes pour tout traiter dans l'URI, cela signifie que vous pouvez utiliser / (barre oblique) pour séparer tout ce dont vous avez besoin ou paramètres de requête. Nous savons qu'il y a des limites à cela, mais c'est le modèle d'architecture.

En suivant le modèle de ROA dans REST, une recherche n’est pas plus que toute autre ressource. La seule différence est que les ressources proviennent d’un calcul et non d’une relation directe avec l’objet lui-même. Sur la base du principe, je pouvais aborder et obtenir un service de calcul arithmétique simple basé sur le schéma suivant:

http://myapi.com/sum/1/2

Où somme, 1 et 2 peuvent être modifiés mais le résultat du calcul est unique et adressable, chaque fois que j'appelle avec les mêmes paramètres j'obtiens le même et rien ne change dans le service. Les ressources / somme / 1/2 et / soustraire / 5/4 respectent parfaitement les principes.


3

GET est ok, si vous avez une collection statique qui retourne toujours les mêmes résultats (représentation) pour un seul URI. Cela implique également que les données générant ces représentations ne sont jamais altérées. La source est une base de données en lecture seule.

Le fait que GET renvoie des résultats différents pour un même URI enfreint l' idempotence / la sécurité et le principe CoolURI et n'est par conséquent pas réactif . Il est possible que des verbes idempotents écrivent dans une base de données, mais ils ne doivent jamais affecter la représentation.

Une recherche commune commence par une requête POST qui renvoie une référence au résultat. Il génère le résultat (il est nouveau et peut être récupéré avec un GET ultérieur). Ce résultat peut être hiérarchique (références ultérieures avec des URI que vous pouvez obtenir), bien sûr, et peut réutiliser des éléments de recherches précédentes, si cela a du sens pour l'application.

En passant, je sais que les gens le font différemment. Vous n'avez pas besoin de m'expliquer à quel point il peut être pratique de violer REST.


Aaaaaaaah - c'est donc comme ça que ça doit fonctionner! Merci!
Rob Baillie

1
Idempotency ne signifie pas qu’il doit toujours retourner exactement la même chose, il doit aussi la retourner si RIEN ne change. La recherche peut être considérée comme le résultat d'un calcul et c'est une ressource elle-même.
Maximiliano Rios

Idempotency signifie en réalité que le résultat reste le même. Vous pouvez, et il est pratique, d’utiliser le contrôle du cache. Et vous pouvez bien sûr utiliser DELETE qui interfère avec les GET ultérieurs. Toutefois, si un agent doit conserver des informations sur le fonctionnement interne de l'application, il n'est plus RESTful. Ci-dessus, je parlais de l'idée la plus extrême de REST. En pratique, les gens peuvent en violer de nombreux aspects. Ils paient le prix lorsque les caches ne cachent plus efficacement.
Martin Sugioarto

"Idempotency signifie en réalité que le résultat reste le même." ... après la requête. Je pense que le fait est que cette demande ne modifie pas les données.
AndreiMotinga
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.