When to use @QueryParam vs @PathParam
I am not asking the question that is already asked here: What is the difference between @PathParam and @QueryParam
This is a "best practices" or convention question.
When would you use @PathParam
vs @QueryParam
.
What I can think of that the decision might be using the two to differentiate the information pattern. Let me illustrate below my LTPO - less than perfect observation.
PathParam use could be reserved for information category, which would fall nicely into a branch of an information tree. PathParam could be used to drill down to entity class hierarchy.
Whereas, QueryParam could be reserved for specifying attributes to locate the instance of a class.
For example,
/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) ;
I don't think there is a standard convention of doing it. Is there? However, I would like to hear of how people use PathParam vs QueryParam to differentiate their information like I exemplified above. I would also love to hear the reason behind the practice.
REST may not be a standard as such, but reading up on general REST documentation and blog posts should give you some guidelines for a good way to structure API URLs. Most rest APIs tend to only have resource names and resource IDs in the path. Such as:
/departments/{dept}/employees/{id}
Some REST APIs use query strings for filtering, pagination and sorting, but Since REST isn't a strict standard I'd recommend checking some REST APIs out there such as github and stackoverflow and see what could work well for your use case.
I'd recommend putting any required parameters in the path, and any optional parameters should certainly be query string parameters. Putting optional parameters in the path will end up getting really messy when trying to write URL handlers that match different combinations.
This is what I do.
If there is a scenario to retrieve a record based on id, for example you need to get the details of the employee whose id is 15, then you can have resource with @PathParam.
GET /employee/{id}
If there is a scenario where you need to get the details of all employees but only 10 at a time, you may use query param
GET /employee?start=1&size=10
This says that starting employee id 1 get ten records.
To summarize, use @PathParam for retrieval based on id. User @QueryParam for filter or if you have any fixed list of options that user can pass.
I think that if the parameter identifies a specific entity you should use a path variable. For example, to get all the posts on my blog I request
GET: myserver.com/myblog/posts
to get the post with id = 123, I would request
GET: myserver.com/myblog/posts/123
but to filter my list of posts, and get all posts since Jan 1, 2013, I would request
GET: myserver.com/myblog/posts?since=2013-01-01
In the first example "posts" identifies a specific entity (the entire collection of blog posts). In the second example, "123" also represents a specific entity (a single blog post). But in the last example, the parameter "since=2013-01-01" is a request to filter the posts collection not a specific entity. Pagination and ordering would be another good example, i.e.
GET: myserver.com/myblog/posts?page=2&order=backward
Hope that helps. :-)
I personally used the approach of "if it makes sense for the user to bookmark a URLwhich includes these parameters then use PathParam".
For instance, if the URL for a user profile includes some profile id parameter, since this can be bookmarked by the user and/or emailed around, I would include that profile id as a path parameter. Also, another considerent to this is that the page denoted by the URL which includes the path param doesn't change -- the user will set up his/her profile, save it, and then unlikely to change that much from there on; this means webcrawlers/search engines/browsers/etc can cache this page nicely based on the path.
If a parameter passed in the URL is likely to change the page layout/content then I'd use that as a queryparam. For instance, if the profile URL supports a parameter which specifies whether to show the user email or not, I would consider that to be a query param. (I know, arguably, you could say that the &noemail=1
or whatever parameter it is can be used as a path param and generates 2 separate pages -- one with the email on it, one without it -- but logically that's not the case: it is still the same page with or without certain attributes shown.
Hope this helps -- I appreciate the explanation might be a bit fuzzy :)