2

Let's say you had a /companies resource that allowed clients to lookup public companies and you wanted clients to be able to lookup companies by Ticker, Location, and Location and industry

Would you keep the same URL in the form:

  • GET /companies/msft
  • GET /companies/usa
  • GET /companies/usa&software

This doesn't seem right. Any ideas?

Marcus Leon
  • 55,199
  • 118
  • 297
  • 429

3 Answers3

9

How about?

GET /Companies?ticker=MSFT

GET /Companies?country=USA

GET /Companies?country=USA&industry=software

The important thing is to identify the resource. The resource is "a list of Companies". Its media type could be an Atom list, or just an HTML document using UL LI tags. The query parameters affect the contents of the list, but conceptually, it is still "a list of companies".

You could create a distinct resource such as

GET /Companies/USA

but do you really need to. Are you going to POST to /Companies/USA? Are you going to delete /Companies/USA? If your application does not require the ability to perform additional operations on these specific sets of companies then why bother modeling them as distinct resources?

As a side note to this discussion, I like to distinguish more clearly when I am accessing a resource which is a single entity versus a list. i.e.

GET /Companies/USA

GET /Company/MSFT

I realize this is not the way some of the popular web frameworks work, but I have found it a useful distinction.

Darrel Miller
  • 139,164
  • 32
  • 194
  • 243
  • We would want to perform operations at the company level. Ie: /companies/msft – Marcus Leon Oct 25 '09 at 21:45
  • See my update. I find the url /Companies/msft misleading. Is it returning a list of companies that have the ticker msft? or is it returning a representation of the the company resource? That's just my preference anyway. Url naming is about as significant to REST as class naming is to object oriented programming. – Darrel Miller Oct 25 '09 at 21:58
  • Maybe a different question but how would you handle urls where the companies could have two different ids (ie msft and a numerical id)? Do you allow gets to both /company/msft and /company/12345 where both the requests return Microsoft's info? – Marcus Leon Oct 25 '09 at 22:12
  • You shouldn't have a single resource with multiple names. If you want aliases, those aliases can send redirects to the actual resource. So, GET /company/msft returns a 301 "Redirect Permanently", and the URL of the actual resource. – Will Hartung Oct 25 '09 at 22:27
  • Why is multiple resource names bad? – Marcus Leon Oct 25 '09 at 22:37
  • 1
    @Marcus I struggled with this same issue for quite a while. I eventually gave up trying to support direct access to a resource using an alternate key in an URL. Now, if I need to "find" a resource through a secondary key then I treat the operation like any other kind of search. GET /Companies?ticker=MSFT and then get the canonical URL '/Company/1234' from the entry in the returned list. The debate as to whether a resource can have multiple URLs continues to rage on and there seems to be one camp that says you should never do it and another that says it is ok under certain circumstances. – Darrel Miller Oct 26 '09 at 01:31
  • I think the main reason why people say two urls for the same resource is bad is because of caching. If you PUT to one of the URLs, how does the cache know to invalidate its copy of the response from the alternate URL. – Darrel Miller Oct 26 '09 at 01:32
  • @Darrel Miller: /Companies/msft returns "msft" the company. If you want companies with the ticker of "msft" (which in this use-case is only one, but whatever) use /Companies?ticker=msft as you even have above. – MikeSchinkel Aug 15 '10 at 19:48
0

You could accept any of those, but then return a Location: header pointing to the canonical address (presumably GET /companies/msft).

John Hyland
  • 6,855
  • 28
  • 32
0

You have only one company, but multiple ways of getting to it, so I'd probably define /companies/[unique-name], and then various things like /companies/byticker/msft and /companies/bylocation/usa etc.

ankon
  • 4,128
  • 2
  • 26
  • 26
  • That's not a very RESTful approach. – workmad3 Oct 25 '09 at 21:36
  • 1
    @workmad3 If you are going use that phrase, you need to explain which REST constraint is being violated. We are seeing *WAY* too much of use of the phrase "that's not RESTful" without any substantiation. – Darrel Miller Oct 25 '09 at 21:43
  • It's not RESTful because resources should have unique names. If you have several queries that return "the same thing", then they should return the unique name of the resource that can then be fetched rather than the resource itself. Having a unique name is important for cache coherency in a REST architecture. One name, one cache policy, one "place" to get it, change it, etc. – Will Hartung Oct 25 '09 at 22:24
  • I understand, sorry for not being clear: the uniquely named thing should be exactly the resource, the other parts would be aliases as you pointed up above, and return permanent redirects to the unique name in case they really are unique, or to resource collections ('USA' is not just Microsoft). – ankon Oct 25 '09 at 22:50
  • @Will How do you feel about pretty much all the "REST" frameworks that allow you to do GET /MyResource.xml and GET /MyResource.json? Two URLs one resource. I'm not taking either side, I'm just saying... – Darrel Miller Oct 26 '09 at 01:34
  • @Darrel - Those suffer the same problem. The key concern here is that the XML and JSON are semantically identical, they ARE the same resource. The trick is that they have different representations. Many would argue that GET /resource.xml is the same as GET /resource with an Accept: application/xml header. The real game here, though, is ensuring that your caching is correct. Making sure that both resources have identical cache policies. For example, you may want to ensure that both the JSON and XML representations expire at the same time, etags change similarly, etc. Only 0 characters are left. – Will Hartung Oct 26 '09 at 07:19
  • @Will Seems like Roy thinks that /Resource.xml, /Resource.json and /Resource are three different resources. I guess that makes both of us right and wrong at the same time :-) http://tech.groups.yahoo.com/group/rest-discuss/message/13960 – Darrel Miller Oct 28 '09 at 00:47
  • @Will: A resource and a representation are two different things. You can't have a resource without a unique name because the name identifies the resource. You can have two resources that return an identical representation and one that means the same thing outside of the definition of resource. See http://stackoverflow.com/questions/1711653/three-step-buyonline-the-restful-way#comment-1591240 which references Fielding's thesis. – MikeSchinkel Aug 15 '10 at 19:57