skip to Main Content

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


  1. 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

    Login or Signup to reply.
  2. REST does not have URI naming conventions.

    The issue I see with supporting

    GET /api/items/{id} 
    GET /api/items/favorite
    

    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

    GET /api/items?type=favorite&latitude=xxx&longitude=xxx&distance=xxx
    

    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.

    GET /api/items/{id}?favorite=true&personal=false
    GET /api/nearest-items/latitude=xxx&longitude=xxx&distance=xxx
        [optional ?favorite and ?personal query params] 
    

    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.

    GET /api/items?nearestTo=12.34,54.40,5&favorite=true
    

    That’s not very human-readable, but are humans really going to read your URIs?

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search