April 24th, 2008

In part 1 of this two-part post, I explained my concern that the word
“resource” has become too closely associated in Rails-related usage
with some combination of model, database table, and controller/model
stack—none of which do justice, as definitions or even first
approximations, to the concept of a REST resource as originally
described by Roy Fielding. Here, I’m going to expand on this
observation by exploring a few ramifications of the same topic.

Resources, controllers, and models (or lack thereof)

As I explained in the previous post, the concept of “resource” has no
database implications—indeed, no implementation implications.
A resource does not have to have a corresponding model. It also does
not have to have a corresponding controller. Resources are far more
high-level than controllers and models. Controllers and models are
tools with which you provide access to representations of resources.

However, if you want to draw a line between resources and Rails, by
far the better line to draw is the one that points to controllers
rather than models. A controller is not a resource, but it comes
closer than anything else in your application to taking on the
features of your resources. Models are another big step away.

If controllers are closest to resources, how does this play out? One
way is in the creation of resources for which requests are handled by
a controller that has no corresponding model.

My favorite example of a likely modelless resource is the shopping
cart. In Ruby for Rails, I use a shopping cart in my central
example. When I started working on this application, I tried to model
it directly; I imagined I would have a ShoppingCart class, a
shopping_carts table, and so forth.

I quickly realized, however, that I didn’t need that. What I was
calling a “shopping cart” was really a virtual construct or, in Rails
terms, a view. I had Order objects and Customer objects, and the shopping
cart was basically a screen showing all of a particular customer’s
open orders. Calling it a “shopping cart” was just a kind of semantic
sugar. There was no need to persist it separately from the persistence
of the orders and the customer.

If I were writing the same application today using RESTful idioms, I
would in all likelihood do:

map.resources :customers do |c|
c.resource :shopping_cart
end

or words to that effect. I would then have a shopping_carts
controller, with a show action (probably leaving all the related CRUD
stuff back in the orders controller, though there might be several
ways to approach that part of it). And I would, without hesitation, describe
the
shopping cart as a resource—even though it has no ShoppingCart
model behind it. From
the perspective of the consumers of my resources, it doesn’t matter
whether there’s a ShoppingCart model (and shopping_carts database
table) or not. I can decide on the best application design, and use
RESTful Rails techniques to support my design decisions appropriately.

A resource is not a model, and it’s also not a controller. Identifying
the resource with the controller is, however, somewhat closer to the
mark. The controller layer conforms most closely to the resource
mapping, which makes sense since the controller is the port of call
when someone connects to your application.

Another area where misunderstandings arise in the course of designing RESTful services in Rails
is in the matter of how identifiers (URI) map to resources—and not just how, but
how many.

Identifiers and resources: not always one-to-one

I’ve seen people tie themselves in knots trying to come up with the
best way to label and/or nest resources. One of the principles that’s
gotten lost in the mix is that the ratio between resources and
identifiers does not have to be one-to-one. Fielding states:

[A] resource can have many identifiers. In other words, there may exist
two or more different URI that have equivalent semantics when used to
access a server. It is also possible to have two URI that result in
the same mechanism being used upon access to the server, and yet those
URI identify two different resources because they don’t mean the same
thing.

Therefore, it’s possible that this:

http://dabsite.com

and this:

http://dabsite.com/welcome

can identify the same resource, which would probably be described as
something like “The welcome and orientation information at
dabsite.com”. The reason they’re the same resource is not that they
generate the same HTML. Rather, they’re the same resource because
they’re published as the same resource.

It’s also possible that this:

http://dabsite.com/orders/211 # 211th order in the system

and this:

http://dabsite.com/orders/042208-003 # third order placed on 4/22/08

identify different resources, even if the third order placed on
4/22/08 happens to be the 211th order in the system. That’s because
resources are not database rows. In this case, the two requests might
generate the same HTML, but still pertain to different resources.

You don’t have to make a point of having a non-one-to-one ratio
between your resources and your identifiers. Just be aware that if
such a ratio emerges, in either direction, you’re not doing anything
inherently “unRESTful.”

CRUD and REST and resources

One of the nice things about the REST support in Rails is that it
dovetails with CRUD-based thinking about modeling. I add in haste:
REST is not CRUD, and CRUD is not REST. (That’s no secret, but I want
to go on record with it.) But in Rails, there’s a nice relationship
between them.

The REST support in Rails emphasizes the convention of CRUD
operations. map.resources gives you a fistful of named routes that
have built-in knowledge of CRUD action names. The emphasis on CRUD at
this level encourages you to think of modeling for CRUD. Instead of
having, say, a users controller with a borrow_book action, you can
have a loans controller with a create action. In many cases, this
way of thinking might also wag the dog of your domain modeling. Thinking
about CRUD in the controller might, for example, lead you to conclude that
you should have a Loan model.

It’s perfectly fine—indeed, in my view, it’s very productive—to
think along these lines, to bring your modeling and your REST-friendly
CRUD operations into harmony, as long as you understand that none of this
is actually about resources as such. Rather, it’s about the Rails
flavor of implementing the handlers that underpin the creation of
resource representations.

Does that sound like just a lot of extra words? It isn’t. It’s a lot
of words, but they’re not extra. Again, it’s important not to squeeze
the entire framework into the “resource” label. Let a resource be a
resource, and let the handler layers be handler layers. They’re nicely
engineered—but they’re not resources.

And then there’s the word “representation,” which crept into my “extra words”
sentence but which is the least extra of all of them.

Representations: the one that got away

The representation is, in my view, the one that got away: the central
concept in REST that no one in the Rails world ever seems to talk
about. We need to, though. It’s vitally important.

Your server does not traffic in resources. It traffics in
representations of resources. Users of your application do not receive
resources. They receive representations. The distinction is big; at
stake is the entire meaning, and meaningfulness, of the notion of a
resource.

We need the concept of “representation” because it’s the part of REST
theory that relieves the pressure on the term “resource.” After all, how can a resource be a
“conceptual mapping” (Fielding) and a sequence of bytes that a server sends
you and a controller-model stack…? It can’t, and it’s only
the first of these things. The second, the response itself, delivers a
representation of a resource.

One resource can have many representations. There’s no big news here;
we all know that a server can give us a text version of Jane Eyre or
a movie version or an audio version. (I’ll refrain from getting philosophical
about whether or not a book and a movie are “the same” in any deep sense.
They’re the same enough, in this context.) The point is that we don’t need to
mush everything into the term “resource.” Rather, we benefit by
yanking that term up to the high level where it belongs, and applying
the term “representation” to the actual response we’re getting.

Fielding has much more on representations in his dissertation, and I’m
not going to try to paraphrase it here. My point is to encourage the
liberal use of the term in Rails discourse about REST. The poor term
“resource” has already been given too much to do. We need to delegate
some of the domain description to the other terms that apply to it.

Now what?

The use of the term “resource” to mean things that, I’ve argued here, it
really doesn’t mean is rather deeply entrenched, and widespread, in Rails
discourse. I don’t have any quick fix for this. I do have a few recommendations, though.

Second, pay particular attention to the concept of the representation. I don’t think we
can get much further in exploring REST and Rails unless the representation makes a
comeback. “Resource” is just plain spread too thin in the way it’s used in and around
Rails, and there’s no reason why it has to be, if we look at the theory as a whole.

Third, and last, don’t assume that any deviation from the out-of-the-box behaviors
in your RESTful Rails applications is unRESTful. The defaults are in place because
they’re high percentage. But they’re just as opinionated as the rest of Rails, and in
some respects more so. That’s OK, but do understand that they’re REST-friendly tools.
They’re not a definitive statement on the entirety of what REST is.

REST is not an easy topic, and it’s unlikely that anyone is
going to create a way for you to create and maintain RESTful applications, over time,
without you trying to get a handle on it and developing your own understanding of
resources, representations, requests, and responses. I hope these posts will help you out in that endeavor.