Not being one to stick with what I know, over the last few days I've been trying to put a RESTful sheen on a small app I'm toying with. It's quite simple -- there's really only one type of resource I need to deal with, and I've got a solid URI structure to refer to it all. So far, so good.
I've read all the theoretical stuff about how URIs should be nouns, and the HTTP action should be the verb -- and I agree with the sentiment, at least for this system I'm writing. I can even (I think) model all of that stuff using my framework of choice, the ever-hyped-but-good-despite-that Ruby on Rails. There's even fairly explicit support in Rails for a lot of what I want to do, with automatic Content-Type: and Accept: handling logic built-in.
But this thing is, primarily, a web app, not a web service. I want the RESTful thing so I can interact with the app programmatically, but at the end of the day, I expect most interactions will be via the good ol' HTML.
How, then, do I implement my HTML interface so that my user's browser does the right thing with my resources? My REST resource http://example.com/widgets/1337 will do the right thing if an appropriately-credentialled user issues a DELETE /widgets/1337 request, but how do I tell a browser to do that?
The "traditional" way I've done that sort of thing, in Rails, is to encode the verb in the URL, like so: /widgets/delete/1337, but I completely agree with the idea that a GET request shouldn't modify data. So I'm completely sold on the idea of not encoding actions into the URI itself.
I'm also a DRY kind of guy, and one of the things that has always slightly irritated me about web services is that, when you write them alongside a HTML-oriented webapp, you often have to duplicate logic (even if it's not very much) to get both versions working. Considering that both the webapp and the REST service are using URLs in pretty much the same fashion, it seems very wasteful to have to design two subtly different schemes to handle the two nearly-identical sets of requirements.
So, having written this article without managing to figure the answer for myself, I invite comment (sent to firstname.lastname@example.org, and I'll summarise later). How do I tell a user's browser to issue a DELETE or PUT against a URL? Am I being overly idealistic to expect the two access methods to be somewhat comparable? Should I just give up and encode the action I want in my URL, or maybe the parameters to the POST request? Am I even completely misunderstanding REST, and trying to find answers in it that just aren't there?
1. I have some slight qualms about the idea that every possible interaction with any possible system could be modelled using an unlimited noun set and four verbs, but I'm happy to leave that debate alone for the moment, as I don't have anywhere near enough experience to speak intelligently, and I have more basic problems at the moment anyway.
2. I remember the common story of the website where the 'delete' hyperlinks are regular GET requests, and the first Google spidering of the website causes everything to be deleted, resulting in a very bare database. This is a result I'm keen to avoid.
3. Don't Repeat Yourself -- a phrase that should be tattooed on the inside of every developer's eyelids.