REST API Best practices: Where to put parameters? [closed]

Solution 1:

If there are documented best practices, I have not found them yet. However, here are a few guidelines I use when determining where to put parameters in an url:

Optional parameters tend to be easier to put in the query string.

If you want to return a 404 error when the parameter value does not correspond to an existing resource then I would tend towards a path segment parameter. e.g. /customer/232 where 232 is not a valid customer id.

If however you want to return an empty list then when the parameter is not found then I suggest using query string parameters. e.g. /contacts?name=dave

If a parameter affects an entire subtree of your URI space then use a path segment. e.g. a language parameter /en/document/foo.txt versus /document/foo.txt?language=en

I prefer unique identifiers to be in a path segment rather than a query parameter.

The official rules for URIs are found in this RFC spec here. There is also another very useful RFC spec here that defines rules for parameterizing URIs.

Solution 2:

Late answer but I'll add some additional insight to what has been shared, namely that there are several types of "parameters" to a request, and you should take this into account.

  1. Locators - E.g. resource identifiers such as IDs or action/view
  2. Filters - E.g. parameters that provide a search for, sorting or narrow down the set of results.
  3. State - E.g. session identification, api keys, whatevs.
  4. Content - E.g. data to be stored.

Now let's look at the different places where these parameters could go.

  1. Request headers & cookies
  2. URL query string ("GET" vars)
  3. URL paths
  4. Body query string/multipart ("POST" vars)

Generally you want State to be set in headers or cookies, depending on what type of state information it is. I think we can all agree on this. Use custom http headers (X-My-Header) if you need to.

Similarly, Content only has one place to belong, which is in the request body, either as query strings or as http multipart and/or JSON content. This is consistent with what you receive from the server when it sends you content. So you shouldn't be rude and do it differently.

Locators such as "id=5" or "action=refresh" or "page=2" would make sense to have as a URL path, such as mysite.com/article/5/page=2 where partly you know what each part is supposed to mean (the basics such as article and 5 obviously mean get me the data of type article with id 5) and additional parameters are specified as part of the URI. They can be in the form of page=2, or page/2 if you know that after a certain point in the URI the "folders" are paired key-values.

Filters always go in the query string, because while they are a part of finding the right data, they are only there to return a subset or modification of what the Locators return alone. The search in mysite.com/article/?query=Obama (subset) is a filter, and so is /article/5?order=backwards (modification). Think about what it does, not just what it's called!

If "view" determines output format, then it is a filter (mysite.com/article/5?view=pdf) because it returns a modification of the found resource rather than homing in on which resource we want. If it instead decides which specific part of the article we get to see (mysite.com/article/5/view=summary) then it is a locator.

Remember, narrowing down a set of resources is filtering. Locating something specific within a resource is locating... duh. Subset filtering may return any number of results (even 0). Locating will always find that specific instance of something (if it exists). Modification filtering will return the same data as the locator, except modified (if such a modification is allowed).

Hope this helped give people some eureka moments if they've been lost about where to put stuff!

Solution 3:

It depends on a design. There are no rules for URIs at REST over HTTP (main thing is that they are unique). Often it comes to the matter of taste and intuition...

I take following approach:

  • url path-element: The resource and its path-element forms a directory traversal and a subresource (e.g. /items/{id} , /users/items). When unsure ask your colleagues, if they think that traversal and they think in "another directory" most likely path-element is the right choice
  • url parameter: when there is no traversal really (search resources with multiple query parameters are a very nice example for that)