2

At the moment, my (pretty standard) REST interface looks like this:

POST /foo         # creates a new foo
PUT  /foo/{id}    # updates a specific foo
GET  /foo/{id}    # returns a specific foo
GET  /foo         # returns a collection of foos

Only authenticated clients are able to use these operations. When using GET or PUT, clients can only retrieve or manipulate their own foo instances. So calling GET /foo only returns a list of foos of a particular user, not all existing foos.

What I want to do now is to introduce a REST compliant search. Usually you just would add parameters to the URI, something like this:

GET  /foo?param1=val1&param2=val2&...

However, in this case, I want clients to be able to search all foos and therefore retrieve foos that don't necessarily belong to them. Of course the resource representations would look a bit different, without any sensible client specific data.

Why would I want to do that, what's the purpose?

Imagine an online auction for cars. A user should be able to get a list of own active auctions (cars he/she wants to sell) using GET /cars. On the other hand, users that are looking for a car should be able to perform a search, something like GET /cars?color=metallic-blue.

But I think it's not a good idea to use the same URI for both the search and the the listing of own auctions (altough bot operations return cars), mainly because the resource representations of the response would slightly differ (e.g. the search returns a more general result without any sensible data). But how else could I do it? Just introducing a new URI, maybe something like GET /cars/search?..?

  • 1
    If you're a fan of steroids you could go the OData route: odata.org/getting-started/basic-tutorial/#filter – MetaFight Jul 24 '16 at 22:35
  • OData is a good idea. As your app gets richer, eventually, you'll need to do a transaction, or to do a join, and when you do, you'll have to keep inventing custom stuff, whereas OData has a syntax for these things already. – Erik Eidt Jul 25 '16 at 1:26
  • 3
    I would do something like GET /my/cars for own cars and GET /cars? for search. You may also find that you'll need to differentiate between listings and owned cars not for sale, for example, if people are allowed to document their garage. – Erik Eidt Jul 25 '16 at 1:29
  • 1
    I would certainly go for /users/{userId}/cars and like Erik said /cars for the listings. I would use userId because it's a constant resource at the same url, it won't be changing based on user sessions. It would also allow you in the future to for example build profile pages for the users which should their listings. – Luc Franken Jul 25 '16 at 8:06
1

If you are really providing a REST api, then your api consumers should be relying upon the definition of your media type to understand the links that are available within in. In this perspective, the URI that you choose are opaque - the machine is going to read the uri value as a unit, and will not attempt to extract semantic information fron it.

If you are providing a web api, expecting your api consumers to construct their own uris, then you want to choose spelling where the semantic intent is readily understood by human readers. Suggested design constraints

  • Keep the uri model as simple as you can, so that consumers aren't forced to keep track of a bunch of exceptions
  • Make it easy for the reader to recognize resources that have significantly different semantics
  • Follow the standard URI spelling conventions; hierarchical data in the appropriate path segment, non-hierarchical data in the query.

In this case, you've really got two different car collection resources; the world's collection, and the subset of those that are specific to this user's auctions. So perhaps

# Global collection
/cars/...

# Private collection
/myAuctions/cars/...

With distinct representations, my guess is that you are probably better off making explicit which representation is returned by which resource. That would especially be the case if your domain language had specific terms for the different resources

# Global collection
/cars/.../windowSticker

# Private collection
/myAuctions/cars/.../vehicleHistory

Third audience to consider is your own development team; choosing resource identifiers that are challenging to implement correctly is a last resort. You'll want to be considering how easy it is to recognize which resources are routed to which implementations, making it easy to share implementations when that is the right thing to do while making it hard to share implementations when that is the wrong thing to do, and so on.

  • Sorry for the late response. Until now, it's a REST api (at least I gave my best to make it look like one, including the "HATEOAS style" links). But even if the URIs are opaque from the perspective of clients, isn't it still a good practice to use a clear structure for them? If yes, then my original question still stands. Or would it be viable to just use the web api style URIs that you mentioned above in my REST api? E.g. using /myAuctions/cars/ in the REST api. – ceran Aug 1 '16 at 9:53

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.