views:

253

answers:

4
+2  Q: 

Is this RESTful?

I have a Rails app that needs to expose values from a database as a web service - since I'm using Rails 2.x, I'm going with REST (or at least try). Assuming my resource is Bananas, for which I want to expose several sub-characteristics, consider this:

 - /banana          -> give a summary of the first 10 bananas, in full (all characteristics)
 - /banana/?name=<name>         -> give all characteristics for banana named <name>
 - /banana/?number=<number>         -> give all characteristics for banana number <number>
 - /banana/?name=<name>/peel          -> give peel data for banana named <name>
 - /banana/?number=<number>/length         -> give length data for banana number <number>

I don't want to search for ID, only name or number. And I have about 7 sub-characteristics to expose. Is this RESTful?

Thanks for any feedback!

+4  A: 

I would use these:

  • /banana
  • /banana/blah
  • /banana/123
  • /banana/blah/peel (and /banana/123/peel)
  • /banana/blah/length (and /banana/123/length)

First, common practice for ReSTful URIs is /object_name/id/verb, with some of those absent (but in that order). Of course, this is neither required nor expected.

If all your names aren't made of digits, you don't have to explicitly have name in /banana/name/blah. In fact, if anything, it would be better to have id as identifier: /banana/id/123/peel. Hope this helps.

pitr
it's not very intuitive, though... I thought it made more sense to have everything banana 123 related _under_ /banana/123/ - can this approach be a valid alternative?
sardaukar
you know, I will agree with you, /banana/123/length makes so much more sense. In fact, that's how I do it myself :).
pitr
hey, also check this article out: http://www.theamazingrando.com/blog/?p=107
pitr
I would rename the first route as `/bananas`
Swanand
Where in the world did you get "ReST should be /object_name/id/verb"? Believe it or not REST says pretty much nothing about what your URL's should look like.
Darrel Miller
REST actually says that URIs should not be defined at all as part of your API. This user's suggestion directly violates a constraint of REST, and is simply RPC.
Wahnfrieden
+1  A: 

It is good practice in REST to not use query parameters because query parameters don´t belong to a URL and in REST all resources should be addressable through a URL.

In your example /banana/?name=name should be /banana/name because you are referring a concrete resource.

Even I think /banana/?number=number/length is not good REST style, because you are selecting an attribute through a URL when you should retrieve the whole state with /banana/name . A difference could be /customers/1024/address to get the Customer 1024 address record.

HTH.

PeterMmm
I believe /banana/?name=name is still unique and cache-able... right?
sardaukar
Most proxies and caches won't cache anything with a querystring, as it is implied that it's a query.
serialseb
This practice has nothing to do with REST. It is simply a correct HTTP usage.
Wahnfrieden
+1  A: 

Parameters should only be used for form submission.

Also, URI naming schemas is totally unrelated to REST. The point of REST is to make related resources discoverable via hypertext, not out-of-band conventions, and only from a limit number of entry points. So your /bananas/ entry point might provide the summary info for 10 bananas, but it must also provide the URI for each of those bananas' details resources, as well as the URI to get the summary for the next 10 bananas. Anything else is just RPC.

Wahnfrieden
so I should use /bananas/<name>/length instead of /bananas/?name=<name>/length ?
sardaukar
The way you assemble your URIs is inconsequential, as long as you're not misusing query parameters. The point of REST is that /bananas/ would give a bunch of complete URIs to different banana resources, and each banana resource would give the URI to its length resource (though you could probably just have that as a field in the banana resource response). When you handle URIs this way, they are not only discoverable through hypertext, but you can also change your URIs without breaking clients, as long as the entry point URI doesn't change.
Wahnfrieden
+1  A: 

What Wahnfrieden is talking about is something called Hypermedia as the Engine of Application State (HATEOAS) - a central constraint of REST as defined by Fielding.

In a nutshell, REST application clients never construct URIs themselves. Instead, they follow URIs provided by the application. So, URI templates such as the ones you're asking about are irrelevent at best. You can make them conform to a system if you'd like, but REST says nothing about how your URIs need to look. You could, if you wanted to, arrange it so that every resource in your system was available from http://example.com/{hash}.

Publishing URI templates, such as the ones you're talking about in your question, introduces tight coupling between your application and clients - something REST is trying to prevent.

The problem with understanding hypermedia-driven applications is that almost nobody implements or documents their "RESTful" systems this way.

It might help to think about the interaction between a human and server via a browser. The human only knows about content and links that the server provides through the browser. This is how a RESTful system should be built. If your resources aren't exposing links, they're probably not RESTful.

The advantage is that if you want to change your URI system, for example, to expose the Banana "Peel" attribute through a query parameter instead of a nested URL, you can do it anytime you'd like and no client code needs to be changed because they're not constructing links for themselves.

For an example of a system that embraces the hypertext-driven constraint in REST, check out the Sun Cloud API.

Rich Apodaca