6

We're designing a rest endpoint for retreiving name autocompletion suggestions for hotel names.

Currently it's defined like this: GET /suggest/:term, so that if you queried `/suggest/hil' you would get responses like "Hilton Paris", "Hilton New York", etc.

One of our colleagues argues that this is against REST API design best practices, and that the search term should instead be a query parameter, i.e. /suggest?term=hilt.

Looking around other famous APIs, it seems that they all use a query parameter:

but I'd like to know why; whether the former is actually bad design and what guidelines would get me to make it a query parameter in the first place.

4

REST services are typically focused on resources, with the path separator (forward slash) denoting sub-resources in a hierarchy. Resources are typically things ("nouns" in English) rather than actions ("verbs" in English).

To conform to this style, your "suggest" endpoint (a verb) could be named "suggestions" (a noun) because it provides access to suggestions. Just as an example, a sub-resource for suggestions might be individual suggestions with URLs like /suggest/Hilton%20New%20York where the response could be a link to the actual "Hilton New York" hotel resource.

Actions like "suggest" are typically represented through HTTP verbs, e.g. GET /suggestions/.

Your "term" is essentially a filter, which are typically passed through query parameters or in the request body. A more robust implementation is described in this SO answer.

2

There is couple of comments that I would suggest you.

  1. You name your resource using verb instead of nouns. suggest is not really a good resource name. It give the client the idea that you are building a controller action and REST does not like it. suggestions is a better name. Now you can view it as a resource set of suggestions which is more RESTful.

  2. Starting with the suggestions resource you have 2 way of viewing your API.

    a. Each set of completions is a resource. In this case you can use the endpoint: ./suggestions/hil. Thus you can view it as a single resource that yield all the suggestions begining with hil.

    b. Each resource is an hotel name. In this case the endpoint would look like a query parameter. ./suggestions?begin-with=hil. This allow you to later design an API to add new hotel name.( POST ./suggestions with appropriate body). Query parameter has a more clear understanding for your client as it reveal the intention begin-with, contain, ...

My preference goes to b) as you might guess but I let you own judge for your preference. a) could have some advantage depending on your use case.

  • I hadn't thought of a sub-resource being a set of suggestions, but that's a good option. – Mike Partridge Aug 24 '15 at 14:07
  • @MikePartridge yes, term being a unique resource identifier for suggestions was the way I had thought about it too. – Zoltán Aug 24 '15 at 14:38
  • @mathk You've convinced me so far, but the idempotency of resources argument is a bit unclear to me. So resources should be immutable over time? I could argue that an endpoint like /user/:username displaying user data could be expected to change. So why wouldn't suggestions also be allowed to change if identified by path? – Zoltán Aug 24 '15 at 14:41
  • Idempotency in this context is a property of HTTP methods, meaning that the side-effects of N > 0 identical requests is the same as for a single request. Executing a GET request for a specific resource should always return the same resource without side-effects; the content of that resource may change, but it should be the same resource. – Mike Partridge Aug 24 '15 at 15:17
  • @MikePartridge Thanks for the comment. I should not have mention the awkwardness of a) as it does not violate idempentecy. (Edited) – mathk Aug 24 '15 at 16:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.