Path segment vs query parameters?

3,842 views
Skip to first unread message

ken1

unread,
Oct 24, 2012, 4:02:39 PM10/24/12
to api-...@googlegroups.com

A global company  has many offices all over the world . A same set of country code  is used to describe the employee 's nationality and the location of their working offices.  The employees can be in only one of the following status (active , terminated , inactive) . These status are not stored in a  DB 's field but  derived from some business logic .  



  • particular employee identified by id
    • /employees/id/peter.chan
  • employee collection filtered by status
  • /employees/active
  • /employees/terminated
  • /employees/inactive

  • employee collection filtered by  nationality and location of their working offices
  • /employees/nationality/france
  • /employees/nationality/italy
  • /employees/office/france
  • /employees/office/italy

  • employee collection is filtered by status and nationality/working office :
  • /employees/active/nationality/france
  • /employees/terminated/office/italy


Or simply use these
  • /employees?status=active&nationality=france
  • /employees?status=terminated&office=italy

How to determine when to use  path segment  or query parameter ? What are the differences besides query parameter cannot be cached by the proxy ? Thanks

chris...@gmail.com

unread,
Oct 24, 2012, 4:15:51 PM10/24/12
to api-...@googlegroups.com
On Wed, 24 Oct 2012, ken1 wrote:

> - employee collection is filtered by status and nationality/working
> office :
>
> - /employees/active/nationality/france
> - /employees/terminated/office/italy

You've entered a state here where there is the appearance of hierarchy
where there isn't one. In such an ambiguous state, where you have
multi-dimensionality this is probably a much better way to go:

> - /employees?status=active&nationality=france
> - /employees?status=terminated&office=italy

You get the expessiveness you want without confusion.

> How to determine when to use path segment or query parameter ? What are
> the differences besides query parameter cannot be cached by the proxy ?

Isn't that a broken proxy?

--
Chris Dent http://burningchrome.com/
[...]

ken1

unread,
Oct 24, 2012, 10:19:14 PM10/24/12
to api-...@googlegroups.com
I also like and agree that  /employees?status=terminated&office=italy   is much clear than /employees/terminated/nationality/italy  
 So , for every URI of the employee collection  , a query parameters status ,office  and nationality are supported .

I think employee and location , and employee and status have the hierarchy structure ,so it makes sense to model status and location in the path segment , so `/employees/office/{locationCode} ` and `/employees/{status} will keep.

So for finding all the employees of a given status that work in a given location , we can use one of the following ways:

/employees?status=active&office=france
/employees/office/france?status=active  
/employees/active/office?=france

What do you think about it? How to choose between /employees/active/ or /employees?status=active?

Peter Williams

unread,
Oct 25, 2012, 12:15:01 AM10/25/12
to api-...@googlegroups.com
On Wed, Oct 24, 2012 at 2:15 PM, <chris...@gmail.com> wrote:

> You've entered a state here where there is the appearance of hierarchy
> where there isn't one. In such an ambiguous state, where you have
> multi-dimensionality this is probably a much better way to go:
>
>> - /employees?status=active&nationality=france
>> - /employees?status=terminated&office=italy

+1. Or maybe event matrix uris <http://www.w3.org/DesignIssues/MatrixURIs.html>

Peter
barelyenough.org

Mike Schinkel

unread,
Oct 25, 2012, 2:36:07 AM10/25/12
to api-...@googlegroups.com
Hi Ken, 

On Oct 24, 2012, at 4:15 PM, chris...@gmail.com wrote:
On Wed, 24 Oct 2012, ken1 wrote:

 - employee collection is filtered by status and nationality/working
 office :

 - /employees/active/nationality/france
 - /employees/terminated/office/italy

You've entered a state here where there is the appearance of hierarchy
where there isn't one. In such an ambiguous state, where you have
multi-dimensionality this is probably a much better way to go:

 - /employees?status=active&nationality=france
 - /employees?status=terminated&office=italy

You get the expessiveness you want without confusion.


If you reorder the path segments you will have a hierarchy:

 - /employees/nationality/france/active
 - /employees/office/italy/terminated

Ken your question is mostly one of personal preference.  I prefer the path segment approach when appropriate because it's cleaner and easier to understand by looking at the URL and results in shorter URLs, but it does imply context whereas query parameters are explicit.

Another concern with path segments is future proofing your structure where you need to ask yourself if there might not be ambiguity when future needs arise.  For example, right now you have active, inactive and terminated for your status.  If in the future you need to query employees by the status of their health care plan the use of these terms might become ambiguous and require you to further complicate your URL structure.

Another issue is mutual exclusivity.  What if you need to query for all French nationals working in offices in Italy?

So considering all these things sadly I'd say query parameters are your best bet even though I don't like using them unless I have to.

Or Peter's suggest of matrix URLs is also another approach albeit few people use them so they are not as familiar to some as query parameters.

Hope this helps.


-Mike
P.S. BTW, the purists say that URLs are opaque and can be anything, so they could look like this:

 - /?a=b23bd&b=l6sb7&c=b42mo08&d=pc493s

Of course I think that's like trying to write programs with variable names a, b, c and d and nobody these days beside maybe outliers thinks that would make any sense. IMO same is true for URLs.

justin kruger

unread,
Oct 25, 2012, 1:30:39 PM10/25/12
to api-...@googlegroups.com
Could it be as simple as
path parameters are required/ url cache-able, while query params are optional, and query or object cache-able?
so in this case, path parameters allow you to cache hire up the stack.


I sometimes ask if i would use a different object, collection or thing.

\route to employees collection\{id}
\employees\{id} -> specific employee, this resource might be cached or proxied and is not in flux.

\employees?state=CA -> a list of employees, this list will change based on the query and might be hard to cache depending on your app.

if you intend to cache it, you might want to make the state required.
\emplooyees\CA?

in this way you could write caching rules based on the url, and it's easier to write a regex for 
\employees\{statecode},

than it is for 
\employees?active=true&state=ca
\employees?state=ca&active=true

since query params are not ordered, they should probably only be cached in the most basic of circumstances.

--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group, send email to api-craft+...@googlegroups.com.
Visit this group at http://groups.google.com/group/api-craft?hl=en.
 
 



--
--
--
Justin Kruger
Social Media Software Engineer -
San Francisco, CA

--
http://twitter.com/jdavid
http://www.linkedin.com/in/jdavid

Kristof Kotai

unread,
Oct 25, 2012, 6:03:48 PM10/25/12
to api-...@googlegroups.com
On Wednesday, October 24, 2012 9:02:39 PM UTC+1, ken1 wrote:


How to determine when to use  path segment  or query parameter ? 

Looking at your examples, I think it is obvious that you should pass them as parameters. Although the explanation is quite subjective, I haven't found anyone yet who would argue with my philosophy :) So here it goes:

Look at what you are trying to achieve, you are trying to search for / request a subset of the entire employee collection.
Look at other APIs, how they do it. I think your example is no different than searching for tweets in Twitter's API:


This has a "geocode" parameter, so that it only returns tweets in a specific area, it has a "q" parameter for text based searching, "lang" parameter for restricting tweets in a given language and so on. And still, they don't use:


They put everything in the query string as parameters.

Another thing that I often see people confusing is this: When querying for one specific element in a collection, why do I need to put the ID in the URI? Why not pass it as a query parameter? Like:

GET   /books/:id
GET   /books?id=:id

Here the first one is preferred, because these two have completely different use cases. Try reading them out.
1st: Get me a book that has this ID
2nd: Get me all the books where the ID is this

The second one just feels wrong. Because you should be expecting more books to be returned (in general) but a unique ID will always restrict the resultset to have 1 element. So effectively you are not querying the books collection, or searching in it, you just want one specific item. 

Romain Bessuges-Meusy

unread,
Dec 12, 2012, 5:06:46 PM12/12/12
to api-...@googlegroups.com
Using path segment is tempting because it reminds us URL rewriting, which importance over the past five years has grown until it became a natural standard. Readability and SEO were in my opinion the two main reasons for that. But if we think in API terms, we should avoid the path segment querying.

Sanjiv Thakor

unread,
Jun 11, 2014, 5:55:19 PM6/11/14
to api-...@googlegroups.com
Here is a general Rule of Thumb (if you may) that i try to follow:
Use the URI Path if it adheres to these two criteria (remember its an AND and not a OR here) 
  1) Path represented has a relational hierarchy  (e.g:  /books/1234/renter/SamPete)
      meaning SamPete is a Renter of Book with Id: 1234
  2) Path uniquely identifies  either 'A resource'  OR  "All resources of that type"
      e.g of   'A Resource'    /books/1234
      e.g of   'All Resources'    /books/

Use Query parameters if  (AND and not OR here as well)
  1) it really does not fit into the relational hierarchy
  2) Using the query params help filter a collection of resources where the size of the collection can be greater than or equal to 1.
      If the size of the collection is always  1  then we know that it uniquely identifies one Resource in which 
      case it should most probably belong in the as a Path Param rather than  a query param

So far this rule of thumb has worked quite well   but i would more than anyone else like to see which scenarios this does not hold true and then improve it(Rule of thumb)

Andrew Braae

unread,
Jun 11, 2014, 7:45:53 PM6/11/14
to api-...@googlegroups.com
One advantage of /employees/active/ over /employees?status=active is that it makes it possible/easier to serve the two endpoints /employees and /employees/active/ from different servers.

In a microservices world, the app that looks after employee details (name, email, etc. - maybe extracted from corporate identity server) might be quite unaware of this thing you call "status". That app could serve up /employees but would be unable to serve up /employees/active/.

To stretch this point further, while status is arguably a pretty major and central attribute, what about country-specific things like local pension plans. In a multinational, you would not want or even be able to bake this kind of country-specific stuff into your core systems. That argues even more strongly for using path segments rather than url params.

The downside of course is losing the ability to do multi-criteria searching, which url parameters supports. Horses and courses.

Reply all
Reply to author
Forward
0 new messages