There was a heated discussion a while back between some members of the XDI TC about whether REST was worth pursuing, or whether it even meant anything meaningful in the XDI context. It’s clear that REST has its religious zealots (RESTafarians). and that purity is not possible or even desirable for the rest of us. But as a thought process, REST is seductively elegant—think of everything that your application exposes to the user as a resource rather than a service. It’s a subtle but powerful difference.

When I first heard DHH present the RESTful routing concept at the 2006 Ruby on Rails conference in Chicago, I have to admit I was skeptical. I thought the way that the PUT and DELETE verbs were faked into the process as automatically created parameters was ugly and problematical. Especially ugly was the insertion of verbs into a GET string with semi-colons (i.e. “GET /resource;edit”). I mean, yes it’s legal syntax, but if you are creating an app that’s meant to expose resources for all kinds of user agents running on a wide variety of platforms, who knows what that surprising usage will do? Had DHH finally gone off the rails?

Well no, of course it turns out to just be DHH being his usual quirky opinionated brilliant self. I read a bit more about RESTful routing on several Rails tech blogs, but they were written in typical HOWTO style, and weren’t very helpful. (HOWTO style is where the author goes into excruciating detail on the parts of the topic that any interested reader would already know, and then skips right over the essential details that would give the reader some context.) The light finally dawned when I read the section about RESTful routing in the new second edition of the excellent Agile Web Development with Rails.

RESTful routing in Rails is a way to get a whole set of predetermined routes from one simple routing statement. That’s it. If you agree with DHH’s opinion about how to do REST, you get a lot for a little. If you don’t, no problem. Just proceed to map your routes the (slightly) harder way. This exemplifies precisely what is meant when people say that Rails is “opinionated software”. For more on Rails RESTful routing, do read the post (a short article really) on the Ruby on Rails mailing list by Russ McBride’s dog Lelu.


RESTful resources are acted upon by the four HTTP verbs, GET, POST, PUT and DELETE. Except of course that browsers don’t support PUT and DELETE, so really just GET and POST. You immediately have to start cheating, doing things like “GET /resource;edit”. The preceding produces a form suitable for posting edited data to the resource. Lelu defends this as getting a resource under the “aspect” of edit, not sneaking in a verb, though she worries about it. Personally, I don’t see how ”/resource/edit” is any different, and much cleaner. When it comes to REST, it’s the thought (process) that counts ;-)

If you’re thinking about what you expose to the user in terms of resources, then GET ”/resource/edit” gives you a resource for editing (i.e. a form), and POST ”/resource/edit” submits the edited resource to the server, which knows what to do with it depending on the context. Here’s where things get really interesting. RESTafarians don’t seem to like context—they want each URL/verb combination to always produce the same result. That’s great if you’re a semantic webbie who just wants all data to be free and accessible. But what about access controls? What about users owning their own data, and being in control of who gets it and under what circumstances? When you’re talking about personal and/or sensitive data, flexible and robust access controls are the crucial thing.

This is about me not wanting you to be able to edit my personal profile without my permission, IRAs not DRMs. When you bring up access controls, RESTafarians tend to look away and mumble something about “if only the damn browsers…”

But back here in consensual reality, access controls are central to what I am trying to build. “User-centric” identity and reputation networks have a primary dependency on flexible and robust access controls, and things quickly get crazy if you can’t maintain state on a user session. Is it possible to do this and still think resources, not services? Of course.

First of all, let’s dispense with the hang-up about cookies. They’re just HTTP header info, and are as well established and de-facto standardized as anything else about HTTP. RESTafarians bless basic and digest auth but not cookies, on the academic distinction that REST is supposed to be stateless, and cookies maintain state on the server, while HTTP auth maintains state on the client, so from a protocol point of view it’s more pure. But if you use the more secure digest auth, the client and the server have to share a memory of a nonce and the distinction starts to get a little silly, imho.

A cookie should carry no information except state—an opaque string. It is much more flexible than HTTP auth, allowing the developer to, among other things, use SSL for transmitting credentials, but then drop out of SSL to save overhead for subsequent requests. It allows the user to log out! It’s just not practical for the server to not maintain state/context on a complex series of authenticated and authorized transactions with a client, so let’s just get over it and move on. If it’s not pure REST, well we can still derive benefits from the resources-not-services way of modeling our applications, and purity is highly overrated.


Context is part of what defines a resource in my universe. In an application that stores and displays personal profiles for example, my profile has different properties than someone else’s profile. My profile may have a dependent resource called “my_profile/edit” whereas someone else’s profile, “profile/42”, has no such resource. On the other hand, if my authorization context includes say, “admin”, then in that context there may exist a resource called “profile/edit/42”.

This makes beautiful sense to me. I can organize my application into context dependent modules—under “app/controllers/my” is a controller class (My::InfoController) that has no instance methods, but does the authorization checking and model instantiation for those instances that apply to me. Then I can use inheriting controller classes for the various aspects of the profile, i.e. “My::ProfileController < My::InfoController” and “My::BioController < My::InfoController”, secure in the knowledge that their methods are always exposed under the correct authorization for the context.

The applications I’m working on are all about authentication and authorization, because those are the low-level building blocks of identity and reputation. There can be even finer grained distinctions within authorization realms, and trying to manage those within one flat controller hierarchy would lead to madness—I speak from experience on this. So, controller hierarchies will be based on authorization realms in these applications. Within each realm (for example admin or regular-user) there will be various actions that are possible, depending on authorization modifiers.

Even though this scheme doesn’t use the full-blown Rails RESTful routing, which you can probably tell I’m not that thrilled about anyway, Rails 1.2 does provide a little discussed but very nice new parameter to route mapping which I am planning to make extensive use of:

:conditions => {:method => :get}
:conditions => {:method => :post}

This allows a GET request to be mapped to a particular controller and action, and a POST request to the same URL to be mapped to a different action. So for example GET /my_profile/edit delivers a populated form, and POST /my_profile/edit delivers the form data to the action which does the updating. The distinction between creating a new resource and updating an existing one is handled by the context—if we are not referring to an existing resource in context then we are creating a new one. Thus we can do away with the need for PUT.

That leaves DELETE to deal with, which turns out to be even more fun. A GET request to /resource/delete accesses a “delete_confirm” action that produces an “are you sure” page, which contains a form with submit buttons that say “yes” and “no”. A POST to /resource/delete accesses a “delete” action which does the deletion if the parameter value is “yes” or otherwise redirects somewhere without acting.

And there we have a completely flexible RESTfully organized application (at least imho) using only GET and POST.