REST API Best practices: où mettre les paramètres? [fermé]

une API REST peut avoir des paramètres d'au moins deux façons:

  1. dans le cadre du chemin D'URL (i.e. /api/resource/parametervalue )
  2. comme argument de requête (i.e. /api/resource?parameter=value )

Quelle est la meilleure pratique ici? Existe-t-il des lignes directrices générales sur le moment d'utiliser 1 et 2?

exemple du monde réel: Twitter utilise des paramètres de requête pour spécifier des intervalles. ( http://api.twitter.com/1/statuses/home_timeline.json?since_id=12345&max_id=54321 )

serait-il considéré comme une meilleure conception pour mettre ces paramètres dans le chemin D'URL?

348
demandé sur Rodrigo 2010-10-26 17:45:42

14 réponses

S'il existe des pratiques exemplaires documentées, Je ne les ai pas encore trouvées. Cependant, voici quelques lignes directrices que j'utilise pour déterminer où placer les paramètres dans une url:

les paramètres optionnels ont tendance à être plus faciles à mettre dans la chaîne de requête.

si vous voulez retourner une erreur 404 lorsque la valeur du paramètre ne correspond pas à une ressource existante, alors je tendrais vers un paramètre de segment de chemin. par exemple, /customer/232 où 232 n'est pas valide id de client.

si toutefois vous voulez retourner une liste vide, alors quand le paramètre n'est pas trouvé, je suggère d'utiliser les paramètres de la chaîne de requête. par exemple /contacts?name=dave

si un paramètre affecte un sous-arbre entier de votre espace URI, utilisez un segment de chemin. par exemple, un paramètre de langage /en/document/foo.txt versus /document/foo.txt?language=en

je préfère que les identificateurs uniques soient dans un segment de chemin plutôt qu'un paramètre de requête.

Les règles officielles pour URIs se trouvent dans cette spécification RFC ici . Il y a aussi une autre spécification RFC très utile ici qui définit les règles de paramétrage des URIs.

254
répondu Darrel Miller 2012-03-28 05:47:51

réponse Tardive mais je vais ajouter une idée supplémentaire à ce qui a été partagé, à savoir qu'il existe plusieurs types de "paramètres" à une demande, et vous devriez prendre cela en compte.

  1. Locators - E. G. identificateurs de ressources tels que IDs ou action /view
  2. filtres - E. G. paramètres qui fournissent une recherche, un tri ou un rétrécissement de l'ensemble des résultats.
  3. State-E. G. identification de la session, clés de l'api, whatevs.
  4. Content-E. G. données à stocker.

regardons maintenant les différents endroits où ces paramètres pourraient aller.

  1. en-têtes de Requête & cookies
  2. chaîne de requête URL ("GET" vars)
  3. URL paths
  4. Corps de chaîne de requête/multipart ("POST" vars)

en général, vous voulez que L'État soit défini dans headers ou cookies, selon le type d'informations de l'état qu'il est. Je pense que nous sommes tous d'accord sur ce point. Utilisez des en-têtes http personnalisés (X-My-Header) si vous en avez besoin.

de même, le contenu n'a qu'un seul endroit à appartenir, qui est dans le corps de la requête, soit comme chaîne de requête, soit comme contenu http multipart et/ou JSON. Ceci est cohérent avec ce que vous recevez du serveur quand il vous envoie du contenu. Donc tu ne devrais pas être impolie et le faire différemment.

Locators comme " id=5 "ou" action=refresh "ou" page=2 "serait logique d'avoir comme chemin D'URL, comme mysite.com/article/5/page=2 où en partie vous savez ce que chaque partie est censée signifier (les bases telles que l'article et 5 signifient évidemment me donner les données de l'article de type avec l'id 5) et des paramètres supplémentaires sont spécifiés comme partie de l'URI. Ils peuvent être sous la forme de page=2 , ou page/2 si vous savez qu'après un certain point dans l'URI les "dossiers" sont jumelés valeurs-clés.

filtres toujours aller dans la chaîne de requête, parce que bien qu'ils fassent partie de la recherche des bonnes données, ils ne sont là que pour retourner un sous-ensemble ou une modification de ce que les Locators retournent seuls. La recherche dans mysite.com/article/?query=Obama (sous-ensemble) est un filtre, et est donc /article/5?order=backwards (modification). Pensez à ce qu'il fait, pas seulement à son nom!

si "view" détermine le format de sortie, alors c'est un filtre ( mysite.com/article/5?view=pdf ) parce qu'il renvoie une modification de la ressource trouvée plutôt qu'un homing dans sur quelle ressource nous voulons. S'il décide à la place quelle partie spécifique de l'article nous obtenons à voir ( mysite.com/article/5/view=summary ) alors il est un localisateur.

Souvenez-vous, se rétrécissant vers le bas un ensemble de ressources est le filtrage. Trouver quelque chose de précis dans une ressource, c'est trouver... duh. Le filtrage de sous-ensemble peut renvoyer n'importe quel nombre de résultats (même 0). Localisation trouverez toujours cette instance spécifique de quelque chose (si elle existe). Le filtrage de Modification retournera le même données en tant que Localisateur, sauf modification (si une telle modification est autorisée).

Espère que cela a aidé à donner aux gens une certaine eureka moments s'ils ont été perdus sur où mettre les choses!

152
répondu Tor Valamo 2014-04-04 21:42:05

cela dépend du dessin. Il n'y a pas de règles pour les URIs au repos sur HTTP (la chose principale est qu'ils sont uniques). Souvent, il s'agit de goût et d'intuition...

je prends approche suivante:

  • url path-element: la ressource et son élément path forment un répertoire transversal et une sous-ressource (par exemple /items/{id} , /users/items). Quand vous n'êtes pas sûr demandez à vos collègues, s'ils pensent que traversal et ils pensent dans "un autre répertoire" plus probable est l'élément le bon choix
  • paramètre url: quand il n'y a pas vraiment de traversée (les ressources de recherche avec plusieurs paramètres de requête sont un très bel exemple pour cela)
21
répondu manuel aldana 2010-10-26 18:00:18

IMO les paramètres devraient être meilleurs que les arguments de requête. L'url est utilisée pour identifier la ressource, tandis que les paramètres de requête ajoutés pour spécifier quelle partie de la ressource vous voulez, n'importe quel état que la ressource devrait avoir, etc.

18
répondu PeterWong 2010-10-26 13:52:00

, Comme dans le RESTE de la mise en Œuvre,

1) les variables de chemin sont utilisées pour l'action directe sur les ressources, comme un contact ou une chanson ex..

OBTENEZ etc /api/ressources/{songid} ou

GET etc/api/resource / {contactid} renvoie les données correspondantes.

2) perms de requête / argument sont utilisés pour les ressources in-direct comme les métadonnées d'une chanson ex.., GET /api/ressources/{songid}?métadonnées=genres il retournera les données sur les genres pour la chanson en question.

17
répondu Satish Bellapu 2015-03-20 20:09:23

"Pack" et postez vos données contre le "contexte" de l'univers de ressource locator offre, ce qui signifie #1 pour le plaisir de la recherche.

les limitations de l'Esprit avec le #2. Je préfère les Messages de #1.

note: les limitations sont discutées pour

POST "151970920 il y a une taille max de POST paramètre de contenu?

GET in Est-il une limite à la longueur d'une requête GET? et taille maximale des paramètres D'URL dans _GET

p. S. ces limites sont basées sur les capacités du client (navigateur) et du serveur(configuration).

16
répondu dgm 2017-05-23 10:31:39

selon la URI standard le chemin est pour les paramètres hiérarchiques et la requête est pour les paramètres non hiérarchiques. OFC. il peut être très subjectif, ce qui est hiérarchique pour vous.

dans les situations où plusieurs URI sont assignés à la même ressource, j'aime mettre les paramètres - nécessaires à l'identification - dans le chemin et les paramètres - nécessaires pour construire la représentation - dans la requête. (Pour moi, de cette façon il est plus facile acheminer.)

par exemple:

  • /users/123 et /users/123?fields="name, age"
  • /users et /users?name="John"&age=30

Pour la carte de réduire j'aime utiliser l'une des méthodes suivantes:

  • /users?name="John"&age=30
  • /users/name:John/age:30

c'est donc à vous (et à votre routeur côté serveur) de décider comment construire votre URIs.

note: juste pour mentionner ces paramètres sont des paramètres de requête. Donc ce que vous faites vraiment est de définir un langage de requête simple. Par des requêtes complexes (qui contiennent des opérateurs comme et, ou, plus grand que, etc.) Je vous suggère d'utiliser un langage de requête. Les capacités de URI modèles sont très limitées...

5
répondu inf3rno 2014-09-19 22:12:52

comme un programmeur souvent sur le client-end, je préfère l'argument de requête. En outre, pour moi, il sépare le chemin D'URL des paramètres, ajoute à la clarté, et offre plus d'extensibilité. Il me permet également d'avoir une logique séparée entre le bâtiment URL/URI et le constructeur de paramètres.

je n'aime pas ce que manuel aldana dit à propos de l'autre option si il y a une sorte d'arbre impliqués. Je vois spécifiques à l'utilisateur de pièces boisées comme ça.

4
répondu Joe Plante 2012-10-25 20:51:20

il n'y a pas de règles dures et rapides, mais la règle empirique d'un point de vue purement conceptuel que j'aime utiliser peut se résumer brièvement comme ceci: un chemin URI (par définition) représente une ressource et les paramètres de requête sont essentiellement des modificateurs sur cette ressource. Jusqu'à présent, qui probablement n'aide pas... Avec une API REST, vous avez les principales méthodes pour agir sur une seule ressource en utilisant GET , PUT , et DELETE . Par conséquent, si quelque chose doit être représenté dans le chemin ou comme paramètre peut être réduit à la question de savoir si ces méthodes ont un sens pour la représentation en question. Est-ce que vous PUT quelque chose à ce chemin et serait-il sémantiquement sain de le faire? Vous pouvez bien sûr PUT quelque chose à peu près n'importe où et plier le dos pour le gérer, mais vous devriez être PUT ce qui revient à une représentation de la ressource réelle et non une version inutilement contextualisée de celui-ci. Pour les collections, la même chose peut être fait avec POST . Si vous voulez ajouter à une collection particulière ce qui serait une URL qui a du sens à POST .

cela laisse encore des zones d'ombre car certains chemins pourraient indiquer ce qui revient aux enfants de ressources parentales qui est quelque peu discrétionnaire et dépend de leur utilisation. La seule ligne dure que cela dessine est que tout type de représentation transitive devrait être fait en utilisant un paramètre de requête, puisqu'il n'aurait pas de Ressource sous-jacente.

en réponse à l'exemple du monde réel donné dans la question originale (API Twitter), les paramètres représentent une requête transitive qui filtre sur l'état des ressources (plutôt qu'une hiérarchie). Dans cet exemple particulier, il serait tout à fait déraisonnable d'ajouter à la collection représentée par ces contraintes, et de plus cette requête ne serait pas en mesure d'être représentée comme un chemin qui aurait un sens dans les Termes d'un graphe d'objet.

l'adoption de ce type de perspective axée sur les ressources peut facilement correspondre directement au graphique objet de votre modèle de domaine et conduire la logique de votre API au point où tout fonctionne très proprement et d'une manière assez auto-documentée une fois qu'il entre dans la clarté. Le concept peut également être clarifié en s'éloignant des systèmes qui utilisent le routage D'URL traditionnel associé à un modèle de données normalement mal ajusté (c.-à-d. un RDBMS). Apache Sling would certainement un bon endroit pour commencer. Le concept d'expédition transversale d'objet dans un système comme Zope fournit également un analogue plus clair.

4
répondu Matt Whipple 2012-10-26 21:01:17

Voici mon avis.

Les params de requête

sont utilisés comme méta-données pour une requête. Ils servent de filtre ou de modificateur à un appel de ressources existant.

exemple:

/calendar/2014-08-08/events

devrait donner les événements du calendrier pour cette journée.

si vous voulez des événements pour une catégorie spécifique

/calendar/2014-08-08/events?category=appointments

ou si vous avez besoin d'événements de plus de 30 minutes

/calendar/2014-08-08/events?duration=30

Un test décisif serait de vérifier si la demande peut être servi sans une requête params.

4
répondu Jay 2014-08-14 21:59:02

je suis généralement tendance vers #2, Comme une requête argument (c'est à dire /api/ressources?paramètre=valeur ).

une troisième option consiste à afficher effectivement le paramètre=valeur dans le corps.

c'est parce qu'il fonctionne mieux pour les ressources à Paramètres multiples et est plus extensible pour une utilisation future.

peu importe lequel vous choisissez, assurez-vous d'en choisir un seul, ne pas mélanger et assortir. Cela mène à une API confuse.

2
répondu NorthIsUp 2010-10-26 18:05:08

une "dimension" de ce sujet a été laissée de côté, mais c'est très important: il y a des moments où les "meilleures pratiques" doivent s'accommoder de la plateforme que nous mettons en œuvre ou que nous renforçons avec des capacités de repos.

exemple pratique:

de nombreuses applications web implémentent aujourd'hui l'architecture MVC (Model, View, Controller). Ils supposent qu'un certain chemin standard est fourni, encore plus lorsque ces applications web viennent avec un Option "Activer les URLs SEO".

juste pour mentionner une application web assez célèbre: une boutique e-commerce OpenCart. Lorsque l'administrateur active les URLs " SEO "il s'attend à ce que ces URLs viennent dans un format MVC tout à fait standard comme:

http://www.domain.tld/special-offers/list-all?limit=25

  • special-offers est le contrôleur MVC qui doit traiter L'URL (montrant la page des offres spéciales)

  • list-all est le nom d'action ou de fonction du contrôleur à appeler. ( * )

  • limite = 25 est une option, indiquant que 25 éléments seront affichés par page.

(*) list-all est un nom de fonction fictif que j'ai utilisé pour plus de clarté. En réalité, OpenCart et la plupart des MVC frameworks ont une fonction par défaut, implicite (et habituellement omise dans L'URL) index qui est appelée lorsque l'utilisateur veut une action par défaut pour être effectuée. Ainsi, L'URL du monde réel serait:

http://www.domain.tld/special-offers?limit=25

avec une application maintenant assez standard ou une structure de cadre similaire à celle ci-dessus, vous obtiendrez souvent un serveur web qui est optimisé pour cela, qui réécrit les URLs pour cela (la vraie" URL non SEOed "serait: http://www.domain.tld/index.php?route=special-offers/list-all&limit=25 ).

par conséquent, vous, en tant que développeur, êtes confrontés à traiter avec l'infrastructure existante et d'adapter vos "meilleures pratiques", sauf si vous êtes l'administrateur du système, savoir exactement comment modifier une configuration de réécriture Apache / NGinx (cette dernière peut être désagréable!) et ainsi de suite.

ainsi, votre API REST serait souvent beaucoup mieux en suivant les normes de l'application web référente, à la fois pour la cohérence avec elle et la facilité / vitesse (et donc économie de budget).

pour revenir à l'exemple pratique ci-dessus, une API REST cohérente serait quelque chose avec des URLs comme:

http://www.domain.tld/api/special-offers-list?from=15&limit=25

or (non SEO URLs)

http://www.domain.tld/index.php?route=api/special-offers-list?from=15&limit=25

avec un mélange d'arguments" paths formed "et" query formed".

2
répondu Dario Fumagalli 2014-07-03 11:52:33

je vois beaucoup D'API de repos qui ne gèrent pas bien les paramètres. Un exemple qui se présente souvent est lorsque L'URI comprend des informations personnellement identifiables.

http://software.danielwatrous.com/design-principles-for-rest-apis /

je pense qu'une question corollaire est quand un paramètre ne devrait pas être un paramètre du tout, mais devrait plutôt être déplacé dans l'en-tête 151980920" ou corps de la requête.

1
répondu Daniel Watrous 2014-08-12 16:40:34

C'est une question très intéressante.

vous pouvez utiliser les deux, il n'y a pas de règle stricte sur ce sujet, mais l'utilisation des variables de chemin URI a quelques avantages:

  • Cache : La plupart des services de cache web sur internet ne reçoivent pas de requête lorsqu'ils contiennent des paramètres de requête. Ils font cela parce qu'il y a beaucoup de systèmes RPC utilisant des requêtes GET pour changer les données dans le serveur (fail!! Doit obtenir être une méthode sûre)

mais si vous utilisez des variables path, tous ces services peuvent mettre en cache vos requêtes GET.

  • Hiérarchie : Les variables de chemin peuvent représenter la hiérarchie: /Ville/Rue / Lieu

Il donne à l'utilisateur plus d'informations sur la structure des données.

mais si vos données n'ont pas de relation de hiérarchie, vous pouvez toujours utiliser le chemin variables, à l'aide de virgule ou de point virgule:

/ ville/longitude, latitude

en règle générale, utilisez la virgule Lorsque l'ordre des paramètres est important, utilisez le point-virgule Lorsque l'ordre n'est pas important:

/IconGenerator/rouge;bleu;vert

en dehors de ces raisons, il y a des cas où il est très courant d'utiliser des variables de chaîne de requête:

  • lorsque vous avez besoin du navigateur pour automatiquement mettre des variables de forme HTML dans L'URI
  • quand vous avez affaire à un algorithme. Par exemple, le moteur de recherche google utilise des chaînes de requête:

http:// www.google.com/search?q=rest

pour résumer, il n'y a pas de raison forte d'utiliser une de ces méthodes, mais chaque fois que vous le pouvez, utilisez les variables URI.

0
répondu jfcorugedo 2015-02-13 09:12:21