Rails controllers are proper resources
Thursday, August 9th, 2007I’ve been doing a lot with REST and ROA on and off the job lately (mainly with Eric and Dray, who still does not have a blog.)
The way Rails implements resources is through Controller classes. One thing that came up yesterday, was the argument that the implementation is improper due to the inclusion of both an index and a show action in one Controller. In REST, a resource can be its own entity (ie: an apple), or a collection of of entities (ie: a fruits resource composed of apples, grapes, oranges, etc.) At first glance, the challenge to Rails Controllers seems to stand because a GET to the index action returns a collection of resources, whereas a GET to the show action just returns one resource.
Upon closer inspection though, you’ll see that the confusion comes from focusing on Controller actions. What should really be looked at is the resource (the controller), and how those two requests are addressed (the URI.) Firstly, notice what kind of resource we have… it’s a fruits resource. Next, look at the URI, it is /fruits.
Now that we’ve established that our FruitsController represents a plural resource (a collection of fruit resources), we can move on to explaining the confusion that the index and show actions introduce. A request to /fruits will return all of our fruits. But, the world has many fruits and we don’t want to request them all. Instead, we will fire a GET at /fruits?page=2?limit=10. Although most of you will recognize this as simple pagination, in ROA it is known as the concept of addressibiliy to indicate state in the URI.
Here’s where the confusion is cleared: a request to /fruits/1337 is not requesting a singular resource (in this case a cherry, the most elite of all fruits.) Instead, it is requesting a collection resource (fruits) but using addressibility to indicate state. It is okay to use the URI in REST different ways for addressiblity, because REST is a style and does not have a specification for addressing via URI’s. For example, another way of getting to /fruits/1337 might be /fruits/?page=1337?limit=1.
As a closing note, even though we used the fruits resource collection here and addressed cherry, we could have done it differently still. If you really wanted a singular cherry resource, you can do so in routes.rb by replacing map.resources :fruits with map.resource :cherry (notice that “resource” is singular.) This would map to a singular CherryController to implement the resource. You could access it with a get request to /cherry, which would map to the show action (in this case the index, or list, action does not make sense because cherry is singular.)
