Meilleures pratiques de l’API REST: Où placer les parameters?

Une API REST peut avoir des parameters d’au moins deux manières:

  1. Dans le cadre du chemin URL (par exemple /api/resource/parametervalue )
  2. Comme argument de requête (ie /api/resource?parameter=value )

Quelle est la meilleure pratique ici? Existe-t-il des directives générales concernant l’utilisation de 1 et quand utiliser 2?

Exemple concret: Twitter utilise des parameters 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 préférable de placer ces parameters dans le chemin d’URL?

    S’il existe des meilleures pratiques documentées, je ne les ai pas encore trouvées. Cependant, voici quelques lignes direcsortingces que j’utilise pour déterminer où placer les parameters dans une URL:

    Les parameters facultatifs ont tendance à être plus faciles à insérer dans la chaîne de requête.

    Si vous voulez renvoyer une erreur 404 alors que la valeur du paramètre ne correspond pas à une ressource existante, je devrais tendre vers un paramètre de segment de chemin. par exemple /customer/232 où 232 n’est pas un identifiant client valide.

    Si toutefois vous voulez retourner une liste vide, lorsque le paramètre n’est pas trouvé, je vous suggère d’utiliser les parameters de la chaîne de requête. eg /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 langue /en/document/foo.txt par rapport à /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 les URI se trouvent dans cette spécification RFC ici . Il existe également une autre spécification RFC très utile qui définit les règles de paramétrage des URI.

    Réponse tardive mais je vais append quelques informations supplémentaires à ce qui a été partagé, à savoir qu’il existe plusieurs types de “parameters” à une demande, et vous devriez en tenir compte.

    1. Localisateurs – par exemple, identificateurs de ressources tels que ID ou action / vue
    2. Filtres – Par exemple, les parameters qui permettent de rechercher, de sortinger ou de réduire l’ensemble des résultats.
    3. Etat – Par exemple, identification de session, clés api, whatevs.
    4. Contenu – Par exemple, les données à stocker.

    Maintenant, regardons les différents endroits où ces parameters pourraient aller.

    1. En-têtes et cookies de demande
    2. Chaîne de requête URL (“GET” vars)
    3. Chemins d’URL
    4. Body query ssortingng / multipart (“POST” vars)

    En général, vous voulez que l’état soit défini dans les en-têtes ou les cookies, selon le type d’informations d’état qu’il contient. Je pense que nous pouvons tous être d’accord là-dessus. Utilisez des en-têtes http personnalisés (X-My-Header) si nécessaire.

    De même, le contenu ne possède qu’un seul emplacement, qui se trouve dans le corps de la requête, sous forme de chaînes de requête ou de contenu HTTP multipart et / ou JSON. Cela correspond à ce que vous recevez du serveur lorsqu’il vous envoie du contenu. Donc, vous ne devriez pas être impoli et le faire différemment.

    Des localisateurs tels que “id = 5” ou “action = refresh” ou “page = 2” seraient logiques, par exemple mysite.com/article/5/page=2 où vous savez ce que chaque partie est supposé vouloir dire (les bases telles que article et 5 signifient évidemment obtenir les données de type article avec id 5) et des parameters supplémentaires sont spécifiés dans le cadre de l’URI. Ils peuvent se présenter sous la forme de page=2 ou de page/2 si vous savez qu’après un certain sharepoint l’URI, les “dossiers” sont des valeurs-clés appariées.

    Les filtres vont toujours dans la chaîne de requête, car s’ils font partie de la recherche des bonnes données, ils ne sont là que pour renvoyer un sous-ensemble ou modifier ce que les localisateurs renvoient seuls. La recherche dans mysite.com/article/?query=Obama (sous-ensemble) est un filtre, et donc /article/5?order=backwards (modification). Pensez à ce qu’il fait, pas seulement à ce qu’il appelle!

    Si “view” détermine le format de sortie, alors il s’agit d’un filtre ( mysite.com/article/5?view=pdf ) car il retourne une modification de la ressource trouvée plutôt que de rechercher la ressource souhaitée. Si, à la place, il décide quelle partie spécifique de l’article nous verrons ( mysite.com/article/5/view=summary ), alors c’est un localisateur.

    Rappelez-vous que réduire un ensemble de ressources est un filtrage. Localiser quelque chose de spécifique dans une ressource se situe … duh. Le filtrage de sous-ensemble peut renvoyer un nombre quelconque de résultats (même 0). La localisation trouvera toujours cette instance spécifique de quelque chose (si elle existe). Le filtrage des modifications renverra les mêmes données que le localisateur, sauf celles modifiées (si une telle modification est autorisée).

    J’espère que cela a consortingbué à donner aux gens des moments d’eureka s’ils ont été perdus à propos de l’endroit où placer leurs affaires!

    Cela dépend d’un design. Il n’y a pas de règles pour les URI à REST sur HTTP (l’essentiel est qu’elles sont uniques). Il s’agit souvent de la question du goût et de l’intuition …

    Je prends l’approche suivante:

    • url path-element: La ressource et son élément path forment une traversée de répertoire et une sous-ressource (par exemple / items / {id}, / users / items). En cas de doute, demandez à vos collègues s’ils pensent que cette traversée et ils pensent dans “un autre répertoire” que l’élément de chemin le plus probable est le bon choix.
    • paramètre url: quand il n’y a pas vraiment de traversée (les ressources de recherche avec plusieurs parameters de requête sont un très bon exemple)

    IMO les parameters devraient être mieux comme arguments de requête. L’URL est utilisée pour identifier la ressource, tandis que les parameters de requête ajoutés pour spécifier la partie de la ressource que vous voulez, tout état que la ressource doit avoir, etc.

    Selon la mise en œuvre REST,

    1) Les variables de chemin sont utilisées pour l’action directe sur les ressources, comme un contact ou une chanson ex.
    GET etc / api / resource / {songid} ou
    GET etc / api / resource / {contactid} renverra les données respectives.

    2) Les perms / arguments de requêtes sont utilisés pour les ressources directes comme les métadonnées d’une chanson ex., GET / api / resource / {songid}? Metadata = genres cela renverra les données de genre pour cette chanson particulière.

    “Pack” et POST vos données par rapport au “contexte” fourni par l’univers-resource-locator, ce qui signifie # 1 pour le localisateur.

    Attention aux limitations avec # 2. Je préfère les POST à ​​# 1.

    note: les limitations sont discutées pour

    POST dans Y at-il une taille maximale pour le contenu du paramètre POST?

    GET in Y a-t-il une limite à la longueur d’une requête GET? et taille maximale des parameters d’URL dans _GET

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

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

    Dans les situations où plusieurs URI sont affectés à la même ressource, j’aime placer les parameters – nécessaires pour l’identification – dans le chemin et les parameters – nécessaires pour construire la représentation – dans la requête. (Pour moi, c’est plus facile d’acheminer.)

    Par exemple:

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

    Pour réduire la carte, j’aime utiliser les approches suivantes:

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

    C’est donc à vous (et à votre routeur côté serveur) de savoir comment vous construisez vos URI.

    note: Juste pour mentionner ces parameters sont des parameters de requête. Donc, ce que vous faites réellement, c’est 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 déjà existant. Les capacités des modèles d’URI sont très limitées …

    En tant que programmeur souvent du côté client, je préfère l’argument de requête. De plus, pour moi, cela sépare le chemin d’URL des parameters, ajoute de la clarté et offre plus d’extensibilité. Cela me permet également d’avoir une logique distincte entre le bâtiment URL / URI et le générateur de parameters.

    J’aime bien ce que manuel aldana a dit à propos de l’autre option s’il y a une sorte d’arbre impliqué. Je peux voir des parties spécifiques à l’utilisateur comme celles-là.

    Il n’y a pas de règles ssortingctes, mais la règle empirique d’un sharepoint vue purement conceptuel que j’aime utiliser peut être résumée brièvement comme suit: un chemin URI (par définition) représente une ressource et les parameters de requête sont essentiellement des modificateurs sur cette ressource. . Jusqu’à présent, cela n’aide probablement pas … Avec une API REST, vous disposez des principales méthodes pour agir sur une seule ressource en utilisant GET , PUT et DELETE . Par conséquent, le fait de savoir si quelque chose doit être représenté dans le chemin ou en tant que paramètre peut être réduit à la question de savoir si ces méthodes ont un sens pour la représentation en question. Souhaitez-vous raisonnablement mettre quelque chose sur ce chemin et serait-il sémantiquement judicieux de le faire? Vous pourriez bien sûr mettre quelque chose à peu près n’importe où et plier le back-end pour le gérer, mais vous devriez mettre en place ce qui équivaut à une représentation de la ressource réelle et non pas à une version contextualisée inutilement de celle-ci. Pour les collections, la même chose peut être faite avec POST . Si vous voulez append à une collection particulière, quelle serait l’URL qui convient à POST .

    Cela laisse encore certaines zones grises car certaines voies pourraient indiquer le montant des ressources parentales pour les enfants, 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 doit être fait en utilisant un paramètre de requête, car il ne devrait pas avoir de ressource sous-jacente.

    En réponse à l’exemple concret donné dans la question d’origine (API de Twitter), les parameters représentent une requête transitive qui filtre l’état des ressources (plutôt qu’une hiérarchie). Dans cet exemple particulier, il serait tout à fait déraisonnable d’append à la collection représentée par ces contraintes, et en outre, cette requête ne pourrait pas être représentée comme un chemin qui aurait un sens dans les termes d’un graphe d’object.

    L’adoption de ce type de perspective orientée ressources peut facilement être directement liée au graphe d’object de votre modèle de domaine et conduire la logique de votre API au point que tout fonctionne très proprement et de manière assez auto-documentée une fois clarté. Le concept peut également être clarifié en s’éloignant des systèmes qui utilisent le routage URL traditionnel mappé sur un modèle de données normalement inadapté (un SGBDR). Apache Sling serait certainement un bon sharepoint départ. Le concept de répartition de traversée d’objects dans un système tel que Zope fournit également un analogue plus clair.

    Voici mon avis

    Les parameters de requête sont utilisés comme métadonnées pour une requête. Ils agissent comme filtre ou modificateur pour un appel de ressource existant.

    Exemple:

    /calendar/2014-08-08/events

    devrait donner des événements de calendrier pour ce jour.

    Si vous souhaitez 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 consisterait à vérifier si la requête peut toujours être traitée sans parameters de requête.

    Je tend généralement vers # 2, comme argument de requête (ie / api / resource? Paramètre = valeur).

    Une troisième option consiste à afficher réellement le paramètre = valeur dans le corps.

    En effet, cela fonctionne mieux pour les ressources multi-parameters et est plus extensible pour une utilisation future.

    Quel que soit celui que vous choisissez, assurez-vous de n’en choisir qu’un, ne pas mélanger et assortir. Cela conduit à une API déroutante.

    Une “dimension” de ce sujet a été omise, mais elle est très importante: il arrive que les “meilleures pratiques” entrent en ligne de compte avec la plate-forme que nous implémentons ou augmentons avec les capacités REST.

    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, d’autant plus lorsque ces applications Web comportent une option “Activer les URL SEO”.

    Pour ne citer qu’une application web assez connue: une boutique e-commerce OpenCart. Lorsque l’administrateur active les “URL SEO”, il s’attend à ce que les URL soient au format MVC standard:

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

    • special-offers est le contrôleur MVC qui traitera l’URL (montrant la page des offres spéciales)

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

    • limit = 25 est une option, indiquant que 25 articles 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 frameworks MVC ont une fonction d’ index implicite (et généralement omise dans l’URL) par défaut qui est appelée lorsque l’utilisateur souhaite effectuer une action par défaut. Donc, l’URL du monde réel serait:

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

    Avec une application ou une structure frameworks assez standardisée comme ci-dessus, vous obtiendrez souvent un serveur Web optimisé pour cela, qui réécrira les URL (la véritable “URL non SEOed” serait: http://www.domain.tld/index.php?route=special-offers/list-all&limit=25 ).

    Par conséquent, en tant que développeur, vous devez gérer l’infrastructure existante et adapter vos “meilleures pratiques”, à moins que vous ne soyez l’administrateur du système, sachez exactement comment modifier une configuration de réécriture Apache / NGinx (cette dernière peut être désagréable!). sur.

    Ainsi, votre API REST serait souvent bien meilleure si vous respectez les normes de l’application Web référente, à la fois pour la cohérence avec celle-ci et pour la facilité / la rapidité (et donc l’économie de budget).

    Pour revenir à l’exemple pratique ci-dessus, une API REST cohérente serait quelque chose avec des URL telles que:

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

    ou (URL non SEO)

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

    avec un mélange d’arguments “chemins formés” et d’arguments “interrogés”.

    Je vois beaucoup d’API REST qui ne gèrent pas bien les parameters. 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 de savoir quand un paramètre ne devrait pas être un paramètre du tout, mais devrait plutôt être déplacé dans HEADER ou BODY de la requête.

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

    Vous pouvez les utiliser tous les deux, il n’y a pas de règle ssortingcte sur ce sujet, mais l’utilisation de variables de chemin URI présente certains avantages:

    • Cache : La plupart des services de cache Web sur Internet ne mettent pas en cache les requêtes GET lorsqu’elles contiennent des parameters de requête. Ils font cela parce qu’il y a beaucoup de systèmes RPC utilisant les requêtes GET pour changer les données sur le serveur (échec !! Get doit être une méthode sûre)

    Mais si vous utilisez des variables de chemin, tous ces services peuvent mettre en cache vos requêtes GET.

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

    Il fournit à l’utilisateur plus d’informations sur la structure des données.

    Mais si vos données n’ont pas de relation hiérarchique, vous pouvez toujours utiliser des variables Path, en utilisant une virgule ou un point-virgule:

    / Ville / longitude, latitude

    En règle générale, utilisez la virgule lorsque l’ordre des parameters est important, utilisez un point-virgule lorsque le classement n’a pas d’importance:

    / 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 placer automatiquement des variables de formulaire HTML dans l’URI
    • Lorsque vous avez affaire à un algorithme. Par exemple, le moteur de recherche Google utilise des chaînes de requête:

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

    En résumé, il n’y a pas de raison forte d’utiliser l’une de ces méthodes, mais chaque fois que vous le pouvez, utilisez des variables d’URI.