My entity is called Item.
POST /api/items create a new Item
PUT /api/items/{id} update an existing Item
GET /api/items/{id} get Item by id
However, I need to retrieve items in three different modes: Nearest (by latitude, longitude and distance), Favorite (marked by isFavorite flag) and Personal (inserted by user).
I though I could name the three URLs:
GET /api/items/nearest?latitude=xxx&longitude=xxx&distance=xxx
GET /api/items/favorite
GET /api/items/personal
But as I read this could violate REST naming conventions. Should I use a type parameter (sort of an enumeration)? But that way user could call GET /api/items?type=favorite&latitude=xxx&longitude=xxx&distance=xxx
and that does not make sense.
One last question: Twitter API doesn’t seem to adhere to REST naming conventions, with endpoints like POST statuses/update
or GET direct_messages/sent
. What do you think about that?
2
Answers
REST is not a standard – it’s a concept, so in fact you cannot brutally violate it.
But in your case I would recommend to add one more GET route
GET /api/items?type=favorite|personal|nearest&...
and pass your “mode” as a get query and not mix it with
id
REST does not have URI naming conventions.
The issue I see with supporting
Is that it’s confusing to clients, because sometimes the path segment after
/items
is an id which indicates an individual resource and sometimes it’s a name which indicates a group resource.The issue I see with supporting
is that, as you recognized, it’s problematic to let clients make confusing calls where some query parameters may or may not be applied to the results.
It seems to me that the issue is really the nearest items, since that requires a set of query parameters that don’t make sense in other contexts. One other option would be to use separate top-level endpoints.
Note that this will break horribly if you ever add some other selection criteria which also requires multiple query parameters.
EDIT —–
Hm. Another choice would be to mash the three optional nearest parameters into one.
That’s not very human-readable, but are humans really going to read your URIs?