I’ve commented on the main Rails mailing list and elsewhere about some concerns I have about the way the term “resource” has been adopted into Rails practice and discussions. I’d like to explain those concerns in a little more detail.
In this post, I’ll talk about the definition of a resource and why it’s a good idea not to overpaint the original definition with a redefinition based on the specifics of Rails. In the next, follow-up post, I’ll comment on several closely related issues, including the usefulness of model-less resources, why it’s better (though not perfect) to identify a controller with a resource than to identify a model with a resource, the relation between CRUD and resources, and the role of the “representation”—an important and concept often overlooked in discussions of REST in Rails.
Controller + model: what a resource isn’t
The problem, in a nutshell, is that the term “resource” has come to be understood widely as meaning “ActiveRecord model” or, perhaps more commonly, “controller-model stack.” People say that they’ve “created an item resource” when what they mean is that they’ve generated a item model and an items controller. There’s no reason for there not to be a short, concise term for “name-matched controller-model stack.” But that word should not be “resource.”
Equating “resource” with controller-model stack has the unfortunate effect of leaving us without a term to refer to what Roy Fielding originally meant by “resource”—which is definitely not “controller-model stack” or anything like it. (More on what a resource is presently.) Fielding’s description of a resource is deeply interesting, and worth protecting from terminological drift. Moreover, there’s no loss involved. In fact, by teasing apart the threads of what’s a resource and what isn’t, we can actually get more out of the RESTful tools available in Rails.
Defining “resource” as controller + model severely limits imaginative thought about how a resource, in the original sense, might play out in Rails. By imaginative, I do not mean improvisatory or chaotic. The Rails REST conventions are very powerful and tremendously useful, and I’m fine with being conservative about deviating from them ad hoc. But I wince when I see people agonizing because they’ve manipulated Model A in Controller B, and think that they’ve violated RESTful principles because they’re crossing resource lines. That’s not how it works; that’s not how the concept of resource maps to Rails technology.
Obviously Rails uses controllers and models, so whatever a resource is, somewhere along the line it’s likely to involve those things in a Rails application. The wrong turn, though, is in assuming that a resource is a controller and/or model.
I tend to think that much of this way of viewing the matter comes from the so-called resource scaffolding. It’s easy to understand why Rails developers, presented with a tool that generates a controller-model chain and calls it a “resource,” would either not see the need to question the terminology, or would be reluctant to do so. But there is a need to question it. The term “resource,” as used very commonly in Rails discussions, bears much more resemblance to how it’s used in the context of Rails scaffolding than how it’s used by Fielding. That doesn’t benefit anyone.
Scaffolding or not, something has led people to think that a resource consists of a controller and a matching model. It doesn’t.
What a resource is
Rails is database-intensive, so the temptation exists to conclude that the word “resource” has something to do with database tables and persistence. Fielding could hardly state the case against this perspective more strongly:
The resource is not the storage object. The resource is not a mechanism that the server uses to handle the storage object.
Already one has to wonder how the generation of an ActiveRecord model and migration ever came to be viewed as part of creating a resource per se (as it is in the scaffolding). Anyway—Fielding goes on to define what a resource is:
The resource is a conceptual mapping — the server receives the identifier (which identifies the mapping) and applies it to its current mapping implementation (usually a combination of collection-specific deep tree traversal and/or hash tables) to find the currently responsible handler implementation and the handler implementation then selects the appropriate action+response based on the request content.
This sentence is a bit more complex than the first two, and it’s worth breaking it down for the sake of seeing how it might map to Rails.
The key idea is that a resource is a conceptual mapping. You send a resource identifier to a server. The server sends back a response (a “representation” of the resource, as we learn elsewhere). In between, the server does what it has to in order to generate the response.
The response is a representation, not a resource. And the mechanisms by which the representation is generated are not, themselves, the resource. In Rails, those mechanisms typically include the routing system (which I would roughly identify with what Fielding calls “the current mapping implementation”) and the controller objects with their actions (the “responsible handler implementation”). Again, these mechanisms are not the resource. And the model layer, which lies yet further away in the architecture, is really not the resource.
The benefit of splitting hairs over the terminology is that it points the way to recovering Fielding’s original concept of a resource, of which I don’t get very many glimpses in the typical discussion of RESTful support in Rails. To the extent that you are setting up models and controllers and RESTful routing, you are putting in place the wiring that will allow your system to fulfill its contract as a provider of representations of certain resources. To the extent that you are determining what resources your system is responsible for, you’re performing a task that has no dependency on Rails or any other specific software tools.
The robustness of resources
Part of the problem with using “resource” to refer directly to parts of the Rails application itself is that it introduces a fragility into the concept of resource, and the identity of specific resources, that really shouldn’t be there. If you declare that your system is responsible for the Resource N, then it shouldn’t matter how many controllers, actions, models, and database tables you use. I don’t mean that it doesn’t matter in terms of software design. I mean that Resource N should be above the fray. It should be robust enough not to depend for its identity as a resource on the specifics of the way you handle the mapping of identifiers to representations.
It’s instructive in this context to consider how the concept of “resource” plays out when you’re serving a static HTML page. The way it plays out is the same as the way it plays out when you’re generating a dynamic response. In other words, whether or not something is a resource has nothing to do with the question of whether or not its representations are generated dynamically, nor with the question of whether a database has been queried or a template rendered in the process of the production of a representation.
This is just terminological common sense. Imagine if you were publishing information about resources available through your system, and you had to explain that sometimes they weren’t really “resources” because they didn’t hit a Rails controller and database table. That would be ludicrous. Obviously a resource is a resource, not because of how its representation is generated behind the scenes but because a representation is returned, however it’s generated, based on a mapping of identifiers to request handlers.
So if you start thinking of controllers and models as actually being resources, you’ve painted yourself into a corner where you have no term that describes a resource in a higher-level sense—no way to identify the “conceptual mapping” that Fielding stipulates. Controllers and models are part of the handling and response mechanism. They are not resources.
But once you decouple the notion of resource from the specifics of how Rails applications generate representations of resources, a lot of other things fall into place. In the second half of this essay, I’ll be looking at several REST-related topics that I think benefit directly from the liberating and sense-making effect of observing the distinctions among resource, representation, and handler mechanisms.
Fielding, Roy Thomas. Architectural Styles and the Design of Network-based Software Architectures. Doctoral dissertation, University of California, Irvine, 2000