Quand utiliser @QueryParam vs @PathParam
Je ne pose pas la question qui est déjà posée ici: Quelle est la différence entre @ PathParam et @QueryParam 1519130920"
il s'agit d'une question de" pratiques exemplaires " ou de convention.
quand utiliseriez-vous @PathParam
vs @QueryParam
.
Ce que je peux penser que la décision pourrait être en utilisant les deux à différencier l'information de modèle. Permettez - moi d'illustrer ci-dessous mon LTPO-moins de observation parfaite.
L'utilisation duPathParam pourrait être réservée à une catégorie d'information, qui tomberait bien dans une branche d'un arbre d'information. PathParam peut être utilisé pour creuser jusqu'à la hiérarchie des classes d'entités.
alors que, QueryParam pourrait être réservé pour spécifier des 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 y ait une convention standard pour le faire. Est-il? Cependant, j'aimerais savoir comment les gens utilisent PathParam vs QueryParam pour différencier leurs informations comme je l'ai illustré ci-dessus. J'aimerais aussi entendre la raison derrière la pratique.
13 réponses
REST n'est peut-être pas une norme en tant que telle, mais la lecture de la documentation générale REST et des billets de blog devrait vous donner quelques lignes directrices pour une bonne façon de structurer les URL de L'API. La plupart des API rest ont tendance à n'avoir que des noms de ressources et des ID de ressources dans le chemin. Tels que:
/departments/{dept}/employees/{id}
certains API REST utilisent des chaînes de requête pour le filtrage, la pagination et le tri, mais puisque REST n'est pas une norme stricte, je recommande de vérifier certains API REST là-bas tels que github et stackoverflow et voir ce qui pourrait bien fonctionner pour votre cas d'utilisation.
je recommande de mettre tous les paramètres requis dans le chemin, et tous les paramètres optionnels devraient certainement être des paramètres de chaîne de requête. Mettre des paramètres optionnels dans L'URL finira par devenir vraiment confus quand on essaye d'écrire des gestionnaires D'URL qui correspondent à différentes combinaisons.
C'est ce que je fais.
S'il y a un scénario pour récupérer un document basé sur l'id, par exemple vous devez obtenir les détails de l'employé dont l'id est 15, alors vous pouvez avoir une ressource avec @PathParam.
GET /employee/{id}
S'il y a un scénario où vous devez obtenir les détails de tous les employés mais seulement 10 à la fois, vous pouvez utiliser query param
GET /employee?start=1&size=10
ça dit que le numéro d'identification de l'employé 1 reçoit dix enregistrements.
pour résumer, utilisez @PathParam pour la récupération basée sur id. Utilisateur @QueryParam pour le filtre ou si vous avez une liste fixe d'options que l'utilisateur peut passer.
je pense que si le paramètre identifie une entité spécifique, vous devez utiliser une variable path. Par exemple, pour obtenir tous les messages sur mon blog, je demande
GET: myserver.com/myblog/posts
pour obtenir le poste avec id = 123, je demanderais
GET: myserver.com/myblog/posts/123
mais pour filtrer ma liste de messages, et obtenir tous les messages depuis Jan 1, 2013, je demanderais
GET: myserver.com/myblog/posts?since=2013-01-01
Dans le premier exemple "posts" identifie une entité spécifique (l'ensemble de la collection de billets de blog). Dans le deuxième exemple, "123" représente également une entité spécifique (un seul billet de blog). Mais dans le dernier exemple, le paramètre "depuis=2013-01-01" est une requête pour filtrer les postes de collecte pas une entité spécifique. La Pagination et l'ordre seraient un autre bon exemple, i.e.
GET: myserver.com/myblog/posts?page=2&order=backward
Espère que ça aide. :- )
vous pouvez utiliser les paramètres de requête pour le filtrage et les paramètres de chemin pour le groupement. Le lien suivant contient de bonnes informations sur ce quand utiliser pathParams ou QueryParams
j'ai personnellement utilisé l'approche de "s'il est logique pour l'utilisateur de marquer un signet une URL qui inclut ces paramètres puis utiliser PathParam".
par exemple, si L'URL d'un profil utilisateur inclut un paramètre d'id de profil, puisque celui-ci peut être mis en signet par l'utilisateur et/ou envoyé par e-mail, j'inclurais cet id de profil comme paramètre de chemin. En outre, un autre élément important à cela est que la page dénotée par L'URL qui inclut le chemin param ne change pas -- le l'utilisateur va configurer son profil, le sauvegarder, et puis peu probable de changer que beaucoup à partir de là; cela signifie webcrawlers/moteurs de recherche/navigateurs/etc peut mettre en cache cette page bien basée sur le chemin.
si un paramètre passé dans L'URL est susceptible de changer la mise en page/le contenu, alors je l'utiliserais comme un queryparam. Par exemple, si l'URL du profil supporte un paramètre qui spécifie s'il faut ou non afficher l'email de l'utilisateur, je considérerais que c'est un paramètre de requête param. (Je sais, on pourrait dire que le &noemail=1
ou quel que soit le paramètre qu'il soit peut être utilisé comme param de chemin et génère 2 pages séparées -- une avec l'e-mail dessus, une sans lui -- mais logiquement ce n'est pas le cas: c'est toujours la même page avec ou sans certains attributs affichés.
Espérons que cette aide -- j'apprécie l'explication pourrait être un peu floue :)
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.
comme theon l'a noté, REST n'est pas une norme. Cependant, si vous cherchez à mettre en œuvre une convention URI basée sur des normes, vous pourriez envisager la oData URI convention . Ver 4 a été approuvé comme norme OASIS et des bibliothèques existent pour oData pour diverses langues y compris Java via Apache Olingo . Ne laissez pas le fait que C'est un spawn de Microsoft vous a rebuté depuis qu'il est a obtenu le soutien d'autres joueur de l'industrie ainsi , qui comprennent Red Hat, Citrix, IBM, Blackberry, Drupal, Netflix Facebook et SAP
la raison est en fait 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. Comme quand utiliser une variable path. Je dirais chaque fois que vous avez affaire à des ids ou si la variable path est une direction pour une requête.
De Wikipedia: Localisateur Uniforme De Ressources
a path , qui contient des données, habituellement organisées sous forme hiérarchique , qui apparaît comme une séquence de segments séparés par des barres obliques.
une interrogation facultative , séparée de la partie précédente par un point d'interrogation (?), contenant une chaîne de requête de non-hiérarchique de données .
- selon la conception de L'URL, Nous pourrions implémenter un PathParam pour les données hiérarchiques/directives/composants localisateurs, ou implémenter un QueryParam lorsque les données ne sont pas hiérarchiques. Cela a du sens parce que les chemins sont naturellement ordonnés, alors que les requêtes contiennent des variables qui peuvent être ordonnées arbitrairement (paires variables/valeurs non ordonnées).
un commentateur précédent a écrit,
je pense que si le paramètre identifie une entité spécifique que vous devez utiliser une variable path.
un autre a écrit,
Utiliser @PathParam pour la 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 passer.
un Autre,
je recommande de mettre tous les paramètres requis dans le chemin, et tous les paramètres optionnels devraient certainement paramètres de chaîne de requête.
-cependant, on pourrait mettre en place un système souple, non hiérarchique pour identifier des entités spécifiques! On peut avoir plusieurs index uniques sur une table SQL, et permettre aux entités d'être identifiées en utilisant n'importe quelle combinaison de champs qui constituent un index unique! Différentes combinaisons (peut-être aussi ordonnées différemment), pourraient être utilisées pour les liens de diverses entités liées (référents). Dans ce cas, nous avons peut-être affaire avec des données non hiérarchiques, utilisées pour identifier des entités individuelles - ou dans d'autres cas, pourrait seulement spécifier certaines variables/champs - certains composants des index uniques - et extraire une liste/ensemble d'enregistrements. Dans de tels cas, il pourrait être plus facile, plus logique et plus raisonnable d'implémenter les URLs en tant que QueryParams!
Pourrait une longue chaîne hexadécimale diluer/diminuer la valeur des mots-clés dans le reste du chemin? Il pourrait être intéressant compte tenu du potentiel SEO les implications de placer des variables/valeurs dans le chemin, ou dans la requête , et l'homme-interface implications de savoir si nous voulons que les utilisateurs soient capables de traverser/découverte de la hiérarchie de l'Url en modifiant le contenu de la barre d'adresse. Ma page 404 Not Found utilise des variables SSI pour rediriger automatiquement les URLs cassées vers leur parent! Les robots de recherche peuvent aussi parcourir la hiérarchie des chemins. D'un autre côté, personnellement, lorsque je partage des URLs sur les médias sociaux, je Raye manuellement tout identificateurs - généralement en tronquant la requête à partir de L'URL, en ne laissant que le chemin: dans ce cas, il est utile de placer des identificateurs uniques dans le chemin plutôt que dans la requête. Si nous voulons faciliter l'utilisation des composants path comme une interface utilisateur rudimentaire, cela dépend peut-être du fait que les données/composants soient lisibles par l'utilisateur ou non. La question de la lisibilité humaine est en quelque sorte liée à la question de la hiérarchie: souvent, les données qui peuvent être exprimées sous forme de mots clés lisibles par l'homme sont également 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 une augmentation de l'utilisation des URLs 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 assez proches pour que nous puissions couvrir d'autres cas dans le chemin, et étiqueter une option comme le "cas canonique" .
il y a fondamentalement plusieurs types de questions que nous pourrions réponse avec L'URL pour chaque requête:
- Quel genre de document/ chose demandons-nous/ signifions-nous?
- lequel (s) nous intéresse (s)?
- comment voulons-nous présenter l'information/ les documents?
Q1 est presque certainement le mieux couvert par le chemin, ou par les PathParams. Q3 (qui est probablement contrôlé via un ensemble de paramètres optionnels et de valeurs par défaut ordonnés arbitrairement); is presque certainement mieux couvert par QueryParams. Q2: cela dépend...
- @QueryParam peut être commodément utilisé avec l'annotation de valeur par défaut de sorte que vous pouvez éviter une exception de pointeur null si aucun paramètre de requête n'est passé.
lorsque vous voulez analyser les paramètres d'une requête GET, vous pouvez simplement définir les paramètres respectifs de la méthode qui traitera la requête GET et les annoter avec l'annotation @QueryParam
-
@PathParam extrait l ' URI valeurs et correspond à @Path. Et donc obtient le paramètre d'entrée. 2.1 @PathParam peut être plus d'un et est défini aux arguments des méthodes
@Path ("repos")
public class Abc {
@GET
@Path ("/msg/{p0}/{P1}")
@Produit("text/plain")
chaîne publique ajouter (@PathParam ("p0") entier param1, @PathParam ("p1") entier 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. Ainsi pour L'URI
http://localhost:8080/Restr/rest/msg/4/6 ,
nous obtenons le résultat 10.
en service de repos, JAX-RS fournit @QueryParam et @formaram tous les deux pour accepter les données de la requête HTTP. Un formulaire HTTP peut être soumis par différentes méthodes comme GET et POST.
@QueryParam: accepte la requête GET et lit les données de la chaîne de requête.
@FormParam: Accepte les requêtes POST et récupère les données du formulaire HTML ou de toute requête des médias
vous pouvez prendre en charge à la fois les paramètres de requête et les paramètres de chemin, par exemple, dans le cas d'agrégation de ressources -- lorsque la collecte de sous-Ressources a un sens en elle-même.
/departments/{id}/employees
/employees?dept=id
Les paramètres de requête peuvent prendre en charge le sous-paramétrage hiérarchique et non hiérarchique; les paramètres de chemin sont uniquement hiérarchiques.
les ressources peuvent présenter des hiérarchies multiples. Soutenez des chemins courts si vous allez interroger de larges sous-collections qui se croisent hiérarchique limites.
/inventory?make=toyota&model=corolla
/inventory?year=2014
utilisez les paramètres de requête pour combiner les hiérarchies orthogonales.
/inventory/makes/toyota/models/corolla?year=2014
/inventory/years/2014?make=toyota&model=corolla
/inventory?make=toyota&model=corolla&year=2014
N'utilise que les paramètres de chemin dans le cas de la composition-quand une ressource n'a pas de sens séparé de son parent, et la collection globale de tous les enfants n'est pas une ressource utile en soi.
/words/{id}/definitions
/definitions?word=id // not useful
je donne un exapmle à undersand quand est-ce que nous utilisons @Queryparam
et @pathparam
Par exemple, je prends une ressource est carResource
classe
si vous voulez faire les entrées de votre méthode de la ressource manadatory puis utiliser le type param comme @pathaparam
, si les entrées de votre méthode de la ressource devrait être facultative alors garder ce type param 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 ressource passer le 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 de resoce affichera seulement le modèle de voiture basé de swift
req://address:2020/carWeb/car/search?carcolor=red
si vous donnez comme ceci nous obtiendrons ResourceNotFound exception parce que dans la classe de la ressource de voiture i déclaré carmodel comme @pathPram
c'est-à-dire vous devez Et devez donner le carmodel comme réq uri sinon il ne passera pas la req de ressource, mais si vous ne passez pas la couleur aussi il va passer la req de ressources pourquoi parce que la couleur est @quetyParam
il est facultatif dans la req.
en bref,
@ Pathparam fonctionne pour la valeur en passant par les ressources et la chaîne de requête
- / user/1
- / utilisateur?id=1
@ Queryparam œuvres de valeur en passant seulement de la Chaîne de Requête
- / utilisateur?id=1