web-dev-qa-db-fra.com

Quand utiliser @QueryParam vs @PathParam

Je ne pose pas la question déjà posée ici: Quelle est la différence entre @PathParam et @QueryParam

C’est une question de "bonnes pratiques" ou de convention.

Quand utiliseriez-vous @PathParam vs @QueryParam.

Ce que je peux penser, c'est que la décision pourrait utiliser les deux pour différencier le modèle d’information. Laissez-moi illustrer ci-dessous mon LTPO - observation moins que parfaite.

L'utilisation de PathParam pourrait être réservée à la catégorie d'informations, ce qui tomberait bien dans une branche d'un arbre d'informations. PathParam peut être utilisé pour accéder à la hiérarchie des classes d’entités.

Considérant que, QueryParam pourrait être réservé à la spécification d'attributs pour localiser l'instance d'une classe.

Par exemple,

  • /Vehicle/Car?registration=123
  • /House/Colonial?region=newengland

/category?instance

@GET
@Path("/employee/{dept}")
Patient getEmployee(@PathParam("dept")Long dept, @QueryParam("id")Long id) ;

vs /category/instance

@GET
@Path("/employee/{dept}/{id}")
Patient getEmployee(@PathParam("dept")Long dept, @PathParam("id")Long id) ;

vs ?category+instance

@GET
@Path("/employee")
Patient getEmployee(@QueryParam("dept")Long dept, @QueryParam("id")Long id) ;

Je ne pense pas qu'il existe une convention standard pour le faire. Y a-t-il? Cependant, j'aimerais savoir comment les gens utilisent PathParam vs QueryParam pour différencier leurs informations, comme illustré ci-dessus. J'aimerais aussi connaître la raison de cette pratique.

246
Blessed Geek

REST n'est peut-être pas un standard en tant que tel, mais la lecture de la documentation générale REST et des articles de blog devrait vous donner quelques indications pour bien structurer les URL des API. La plupart des API de repos n'ont généralement que des noms de ressources et des ID de ressources dans le chemin. Tel que:

/departments/{dept}/employees/{id}

Certaines API REST utilisent des chaînes de requête pour le filtrage, la pagination et le tri, mais comme REST n'est pas une norme stricte, je vous recommande de vérifier certaines REST API existantes. tels que github et stackoverflow et voyez ce qui pourrait bien fonctionner pour votre cas d'utilisation.

Je recommanderais de mettre tous les paramètres requis dans le chemin, et tous les paramètres facultatifs devraient certainement être des paramètres de chaîne de requête. Mettre des paramètres facultatifs dans le chemin finira par devenir vraiment compliqué en essayant d'écrire des gestionnaires d'URL correspondant à différentes combinaisons.

228
theon

C'est ce que je fais.

S'il existe un scénario permettant de récupérer un enregistrement en fonction d'un identifiant, par exemple, vous devez obtenir les détails de l'employé dont l'identifiant est 15, vous pouvez alors disposer d'une ressource avec @PathParam.

GET /employee/{id}

Si vous devez obtenir les détails de tous les employés mais seulement de 10 à la fois, vous pouvez utiliser le paramètre query.

GET /employee?start=1&size=10

Cela indique que le premier identifiant d'employé 1 obtient dix enregistrements.

Pour résumer, utilisez @PathParam pour une récupération basée sur l'id. Utilisateur @QueryParam pour le filtre ou si vous avez une liste fixe d'options que l'utilisateur peut transmettre.

82

Je pense que si le paramètre identifie une entité spécifique, vous devez utiliser une variable de chemin. Par exemple, pour obtenir tous les articles de mon blog, je demande

GET: myserver.com/myblog/posts

pour obtenir le message avec id = 123, je demanderais

GET: myserver.com/myblog/posts/123

mais pour filtrer ma liste de messages et obtenir tous les messages depuis le 1 janvier 2013, je demanderais

GET: myserver.com/myblog/posts?since=2013-01-01

Dans le premier exemple, "posts" identifie une entité spécifique (la collection complète de messages de blog). Dans le deuxième exemple, "123" représente également une entité spécifique (un seul post de blog). Mais dans le dernier exemple, le paramètre "since = 2013-01-01" est une demande de filtrage de la collection de publications et non d'une entité spécifique. La pagination et la commande seraient un autre bon exemple, c.-à-d.

GET: myserver.com/myblog/posts?page=2&order=backward

J'espère que ça t'as aidé. :-)

41
10GritSandpaper

J'ai personnellement utilisé l'approche de "s'il est logique pour l'utilisateur de mettre en signet une URL qui inclut ces paramètres, utilisez ensuite PathParam".

Par exemple, si l'URL d'un profil utilisateur inclut un paramètre d'identifiant de profil, étant donné que celui-ci peut être marqué par un signet et/ou envoyé par courrier électronique, j'inclurais cet identifiant de profil en tant que paramètre de chemin d'accès. En outre, il est également important de noter que la page indiquée par l'URL, qui inclut le paramètre path, ne change pas. L'utilisateur va configurer son profil, le sauvegarder, puis il est peu probable qu'il change autant. cela signifie que webcrawlers/moteurs de recherche/navigateurs/etc peut mettre en cache cette page en fonction du chemin.

Si un paramètre passé dans l'URL est susceptible de changer la mise en page/le contenu de la page, je l'utiliserais alors comme un type de paramètre. Par exemple, si l'URL du profil prend en charge un paramètre spécifiant s'il faut afficher le courrier électronique de l'utilisateur ou non, je considérerais cela comme un paramètre de requête. (Je sais, on pourrait soutenir que vous pourriez dire que le &noemail=1 ou un paramètre quelconque peut être utilisé comme paramètre de chemin et génère 2 pages distinctes - une avec l'e-mail dessus, l'autre sans - mais logiquement c'est pas le cas: c'est toujours la même page avec ou sans certains attributs affichés.

J'espère que cela vous aidera - j'apprécie que l'explication soit un peu floue :)

8
Liv

Vous pouvez utiliser des paramètres de requête pour le filtrage et des paramètres de chemin pour le regroupement. Le lien suivant contient de bonnes informations sur ceci Quand utiliser pathParams ou QueryParams

7
Chandra

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

Vous pouvez utiliser les deux, il n'y a pas de règle stricte à ce sujet, mais l'utilisation de variables de chemin d'URI présente certains avantages:

  • Cache: La plupart des services de cache Web sur Internet ne mettent pas en cache les demandes GET lorsqu'ils contiennent des paramètres de requête. Ils le font car de nombreux systèmes RPC utilisent des requêtes GET pour modifier les données sur le serveur (échouez! Get doit être une méthode sûre).

Mais si vous utilisez des variables de chemin, tous ces services peuvent mettre en cache vos demandes 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 aucune relation hiérarchique, vous pouvez toujours utiliser les variables Path, en utilisant une virgule ou un point-virgule:

/ Ville/longitude, latitude

En règle générale, utilisez des virgules lorsque l'ordre des paramètres est important, utilisez des points-virgules lorsque l'ordre n'a pas d'importance:

/ IconGenerator/rouge; bleu; vert

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

  • Lorsque vous avez besoin que le navigateur mette automatiquement des variables de formulaire HTML dans l'URI
  • Quand vous avez affaire à un algorithme. Par exemple, le moteur Google utilise des chaînes de requête:

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

Pour résumer, il n’ya aucune raison forte d’utiliser une de ces méthodes, mais chaque fois que vous le pouvez, utilisez des variables d’URI.

4
jfcorugedo

De Wikipedia: Localisateur de ressources uniforme

Un chemin , contenant des données, généralement organisé sous forme hiérarchique , qui apparaît sous la forme d'une séquence de segments séparés par des barres obliques.

Une requête facultative , séparée de la partie précédente par un point d'interrogation (?), Contenant une chaîne de requête de données non hiérarchiques .

- Selon la conception conceptuelle de l'URL, nous pouvons implémenter un PathParam pour les composants données/directives/localisateurs hiérarchiques, ou implémenter un QueryParam lorsque les données ne sont pas hiérarchiques. Cela a du sens car les chemins sont naturellement ordonnés, alors que les requêtes contiennent des variables qui peuvent être ordonnées de manière arbitraire (paires variable/valeur non ordonnées).

Un intervenant précédent a écrit:

Je pense que si le paramètre identifie une entité spécifique, vous devez utiliser une variable de chemin.

Un autre a écrit,

Utilisez @PathParam pour une récupération basée sur un identifiant. Utilisateur @QueryParam pour le filtre ou si vous avez une liste fixe d'options que l'utilisateur peut transmettre.

Un autre,

Je recommanderais de mettre tous les paramètres requis dans le chemin, et tous les paramètres facultatifs devraient certainement être des paramètres de chaîne de requête.

- Cependant, on pourrait mettre en place un système flexible, non hiérarchique, pour identifier des entités spécifiques! On peut avoir plusieurs index uniques sur une table SQL et permettre l’identification d’entités à l’aide d’une combinaison de champs comprenant un index unique! Différentes combinaisons (peut-être aussi ordonnées différemment) peuvent être utilisées pour les liens de différentes entités apparentées (référants). Dans ce cas, nous pourrions avoir affaire à des données non hiérarchiques, utilisées pour identifier des entités individuelles - ou dans d'autres cas, ne spécifier que certaines variables/champs - certains composants d'index uniques - et récupérer une liste/un ensemble d'enregistrements. Dans de tels cas, il pourrait être plus facile, plus logique et raisonnable d'implémenter les URL en tant que QueryParams!

Une longue chaîne hexadécimale peut-elle diluer/diminuer la valeur des mots-clés dans le reste du chemin? Cela peut valoir la peine d’envisager les implications potentielles pour le référencement de placer des variables/valeurs dans le chemin ou dans la requête , ainsi que les implications pour l’interface humaine de savoir si nous voulons que les utilisateurs puissent parcourir/explorez la hiérarchie des URL en modifiant le contenu de la barre d'adresse. Ma page 404 non trouvée utilise des variables SSI pour rediriger automatiquement les URL cassées vers leur parent! Les robots de recherche peuvent également traverser la hiérarchie des chemins. De mon côté, personnellement, lorsque je partage des URL sur un média social, je supprime manuellement tous les identifiants uniques privés - généralement en tronquant la requête de l'URL, en ne laissant que le chemin: dans ce cas, il est utile de placer des identifiants uniques. dans le chemin plutôt que dans la requête. Que nous voulions faciliter l'utilisation de composants de chemin d'accès en tant qu'interface utilisateur brute, cela dépend peut-être du fait que les données/composants sont lisibles par l'homme ou non. La question de la lisibilité humaine est quelque peu liée à la question de la hiérarchie: souvent, les données pouvant être exprimées sous la forme de mots-clés lisibles par l'homme sont également hiérarchiques; tandis que les données hiérarchiques peuvent souvent être exprimées sous forme de mots-clés lisibles par l'homme. (Les moteurs de recherche eux-mêmes pourraient être définis comme augmentant l'utilisation des URL en tant qu'interface utilisateur.) Les hiérarchies de mots-clés ou de directives peuvent ne pas être strictement ordonnées, mais elles sont généralement suffisamment proches pour que nous puissions couvrir d'autres cas dans le chemin, et nommez une option comme le cas "canonique" .

Il existe fondamentalement plusieurs types de questions auxquelles nous pourrions répondre avec l'URL de chaque demande:

  1. Quel type de disque/chose demandons-nous/servons-nous?
  2. Le (s) quel (s) sommes-nous intéressés?
  3. Comment voulons-nous présenter les informations/enregistrements?

Q1 est presque certainement mieux couvert par le chemin, ou par PathParams. Q3 (qui est probablement contrôlé via un ensemble de paramètres facultatifs et de valeurs par défaut ordonnés de manière arbitraire); est presque certainement mieux couvert par QueryParams. Q2: Cela dépend…

2
Matthew Slyman

Comme l'a noté le sur, REST n'est pas un standard. Cependant, si vous souhaitez implémenter une convention d'URI basée sur des normes, vous pouvez envisager la convention d'URI de oData . La version 4 a été approuvée en tant que norme OASIS et des bibliothèques existent pour oData pour divers langages, notamment Java via Apache Olingo . Ne laissez pas le fait que c'est une recrue de Microsoft qui vous rebute, car obtenu le soutien de tous les acteurs du secteur , qui inclut Red Hat, Citrix, IBM, Blackberry, Drupal, Netflix Facebook et SAP.

Plus d'adoptants sont listés ici

2
MikeM

Je donne un exemple à underand et quand utilisons-nous @Queryparam et @pathparam

Par exemple, je prends une ressource est carResource class

Si vous voulez rendre les entrées de votre méthode de ressource manadatory, utilisez le type param comme @pathaparam, si les entrées de votre méthode resource doivent être optionnelles, conservez ce type comme @QueryParam param

@Path("/car")
class CarResource
{
    @Get
    @produces("text/plain")
    @Path("/search/{carmodel}")
    public String getCarSearch(@PathParam("carmodel")String model,@QueryParam("carcolor")String color) {
        //logic for getting cars based on carmodel and color
            -----
        return cars
    }
}

Pour cette resouce passer la demande

req uri ://address:2020/carWeb/car/search/swift?carcolor=red

Si vous donnez req comme ceci la ressource donnera le modèle de voiture basé et la couleur

 req uri://address:2020/carWeb/car/search/Swift

Si vous donnez req comme ceci, la méthode resoce affichera uniquement Swift car modèle

req://address:2020/carWeb/car/search?carcolor=red

Si vous donnez comme ceci, nous obtiendrons une exception ResourceNotFound car, dans la classe de ressources de voiture, j’ai déclaré carmodel comme étant @pathPram c’est-à-dire que vous devez et devez donner le modèle comme req uri sinon il ne passera pas le req à resouce mais si vous ne le faites pas. Si la couleur est @quetyParam elle est facultative dans req.

1
user4374220

Vous pouvez prendre en charge les paramètres de requête et les paramètres de chemin, par exemple, dans le cas d'une agrégation de ressources - lorsque la collection de sous-ressources a un sens en soi.

/departments/{id}/employees
/employees?dept=id

Les paramètres de requête peuvent prendre en charge les sous-ensembles hiérarchiques et non hiérarchiques. les paramètres de chemin sont uniquement hiérarchiques.

Les ressources peuvent présenter plusieurs hiérarchies. Prenez en charge les chemins d'accès courts si vous interrogez des sous-collections étendues qui transcendent les limites hiérarchiques.

/inventory?make=toyota&model=corolla
/inventory?year=2014

Utilisez des paramètres de requête pour combiner des hiérarchies orthogonales.

/inventory/makes/toyota/models/corolla?year=2014
/inventory/years/2014?make=toyota&model=corolla
/inventory?make=toyota&model=corolla&year=2014

Utilisez uniquement des paramètres de chemin dans le cas de la composition - lorsqu'une ressource n'a pas de sens, qu'elle est séparée de son parent, et que la collection globale de tous les enfants n'est pas une ressource utile en soi.

/words/{id}/definitions
/definitions?word=id   // not useful
1
Steve Mitchell
  1. @QueryParam peut être utilisé de manière pratique avec l'annotation Valeur par défaut afin d'éviter une exception de pointeur null si aucun paramètre de requête n'est transmis.

Lorsque vous souhaitez analyser les paramètres de requête à partir d'une requête GET, vous pouvez simplement définir le paramètre correspondant à la méthode qui gérera la requête GET et les annoter avec l'annotation @QueryParam.

  1. @PathParam extrait les valeurs d'URI et correspond à @Path. Et obtient donc le paramètre d'entrée. 2.1 @PathParam peut être plusieurs et est défini sur les arguments de méthodes

    @Path("/rest")
    public class Abc {
    
        @GET
        @Path("/msg/{p0}/{p1}")
        @Produces("text/plain")
        public String add(@PathParam("p0") Integer param1, @PathParam("p1")  Integer param2 )
        {
            return String.valueOf(param1+param2);
        }
    } 
    

Dans l'exemple ci-dessus,
http://localhost:8080/Restr/rest/msg/{p0}/{p1},
p0 correspond à param1 et p1 correspond à param2. Donc pour l'URI
http://localhost:8080/Restr/rest/msg/4/6,
nous obtenons le résultat 10.

Dans le service REST, JAX-RS fournit @QueryParam et @FormParam pour accepter les données d'une requête HTTP. Un formulaire HTTP peut être soumis par différentes méthodes, telles que GET et POST.

@QueryParam: accepte la demande GET et lit les données de la chaîne de requête.

@FormParam: Accepte la demande POST et extrait les données du formulaire HTML ou de toute demande du support.

1
Amlesh Kumar

La raison est en réalité très simple. Lorsque vous utilisez un paramètre de requête, vous pouvez utiliser des caractères tels que "/" et votre client n'a pas besoin de les encoder en HTML. Il y a d'autres raisons mais c'est un exemple simple. Quant à savoir quand utiliser une variable de chemin. Je dirais que chaque fois que vous avez affaire à des identifiants ou si la variable de chemin est une direction pour une requête.

1
Tony

En résumé,

@Pathparam fonctionne pour la valeur passant par les ressources et la chaîne de requête

  • / utilisateur/1
  • / user? id = 1

@Queryparam fonctionne pour la valeur transmettant uniquement la chaîne de requête

  • / user? id = 1
0
ArulRajP