Useful and Useless REST
By Ian Bicking under Talk, Theory on 22. March 2006With all this talk about High and Low REST, I noticed something in a post by Mark Nottingham:
Don has effectively made the observation that a lot of other people (especially of the Web services sort) have made; while the benefits of GET’s transparency are obvious, they’re less apparent for PUT and DELETE, so why not just take the easy (lo) road and use POST?
I think there are two answers; 1) hopefully, we’ll have some concrete benefits for that transparency some day (think offline), and 2) thinking in terms of GET/PUT/DELETE first — using POST only as an escape hatch — leads you down a path where your application will be using transparent methods a lot more than opaque POSTs.
I’ll use my first post here to repeat the ideas from Bill’s post…
I think a cargo cult of REST has indeed emerged, and I’m seeing evidence of it on the ground, far from SOA discussions. I’m seeing REST evoked as something that is inherently good. I’m seeing people ask for REST support in their frameworks. I usually know what they mean, but their requests seem to be driven by the truthiness of REST, not the utility.
For instance, I often get annoyed with URI design discussions, where people put great importance into abstract design issues that no one else will notice or care about. In HTTP (and REST) URIs are supposed to be opaque strings, so why the obsession? I call bike shed. People are tackling the pointless decisions first, because they are low-stake and easy to think about. It also comes from an inversion of logic: good things are generally aesthetically pleasing; but many things that are aesthetically pleasing are superfluous and distracting.
What’s useful is that REST design doesn’t promise anything more
than it can deliver. It doesn’t promise anything general about the
body of the response (except I suppose that Content-type
and other metadata will be accurate). It doesn’t promise anything about the URI. The use of verbs is in part to make the URI more opaque, so instead of rewriting the URI to express new actions, you use different verbs on the same URI. GET actually means something to intermediaries. POST, PUT, and DELETE only really mean something to humans. Which is okay, but it’s not interesting architecture.
It’s not bad to use these verbs, it’s just not particularly useful. I think High REST may be the result of people who just can’t help but make architecture. Low REST is people who are recognizing emergent architecture. REST isn’t a new idea, it is the recognition of the good ideas that are already around us. And like design patterns, the description is turning into prescription, and as with patterns we are seeing people use REST to justify premature architecture — probably a much worse sin than permature optimization.
I look at a protocol like OpenID which is wedded to HTTP and HTML — and even intimately connected to those poorly-specified browsers that we all can’t help but hate — and I think that’s great architecture. It’s not great because it is pretty underneath (it isn’t), it is great because it solves a hard problem inside fixed constraints without exceeding scope. It’s RESTful at heart, but not RESTful in form.
If there aren’t concrete benefits to using PUT or DELETE over POST, then why should we care? What hard problem is made easy? High REST seems to be uncovering non-problems.
Mark Baker:
Dude, you don’t know what you’re talking about.
comment at 22. March 2006
Ryan Tomayko:
How does that help, Mark? What, all of a sudden you don’t feel like talking?
That’s not really true. Squid, and I believe most other caching proxies have an explicit understanding of each of these verbs. The semantics for each are rigidly defined and are all very different. PUT is not POST and POST is not DELETE. The descriptions of each verb in RFC 2616 are fairly short and straight-forward for the most part.
PUT and DELETE are idempotent and POST isn’t. PUT and DELETE each say something specific about the resource they modify and clients and intermediaries can make assumptions about the resource they PUT/DELETE to once the response is complete. When an APP client PUTs an entry it can then make assumptions (more specific assumptions than POST) about that resource’s state after the request. For a client that stores 1,000 blog entries, that can be important. Sure, you could implement the same exact semantics at the application layer using POST, special parameters, maybe a custom XML response body to indicate success or failure. It would be simple, right? (cue explosion of XML-RPC based blog-publish interfaces) But now we all have to agree on these other ways of accomplishing the same exact thing as PUT, which has already been figured out. If we all agree that a PUT is a PUT is a PUT is a PUT and that you express it as such and such then we can start building things around that understanding. Just like we did with GET and POST.
The trick is in knowing when not to use PUT or DELETE (if you aren’t sure, the rules in rfc2616 are pretty clear and they make good sense too). There are a number of cases that are better suited to POST, even though it may seem like you’re putting or deleting something. I’ve spent quite a bit of time trying to shoe-horn certain types of operations into a PUT or DELETE in an attempt to be “RESTful” only to learn that I was trying too hard and that POST was really the right verb for the situation. It’s sort of like how everyone stopped using
<table>
’s for tabular data when CSS came around.Anyway, the point I’m trying to come around to and probably should have come right out with, is just that I think we should be trying to use the verb that’s most appropriate for the situation. The problem is that it’s not easy to do so. From the perspective of the lazy hacker, the simplest and best choice, given the current set of popular web frameworks and libraries (on both the client and server) is to re-implement PUT and DELETE on top of POST at the application layer every single time. And the lazy hacker is always right. But I think that one day in the maybe not-too-distant future the lazy hacker will change her mind because the tooling around building and interacting with resources using PUT/DELETE will save her time and energy and bring extra advantages instead of being a big nuisance.
No one is going to do this stuff because it’s compelling from a philosophical standpoint. It will take new tools and efficiencies, browsers and client-side libraries, web frameworks that make it easier to do cooler stuff with better clients, etc. The web’s common vernacular will extend into the less explored aspects of HTTP when the practical advantages of doing so present themselves. But that’s what’s so friggin cool and weird about it: HTTP has been around forever and might be only 10% into it’s implementation phase and it’s hard to tell exactly what we should implement next to get the most bang for our buck.
comment at 22. March 2006
Mark Nottingham:
Ian,
I’ve seen the same kinds of discussions (focusing on aesthetics more than function), and have similar concerns; it’s a very easy trap to fall into. Howeer, I draw a different conclusion. As I said, some of the benefits of focusing on these apparently non-productive parts of REST is that they make it more likely that you’ll trip over the productive parts (e.g., caching).
PUT and DELETE, for example, give you a cleaner design if you need those semantics. While you could stuff them inside POST, you’d need to then find a way to dispatch and differentiate them; probably in the URI. And then, you wouldn’t get the benefits of invalidation in caches.
Part of what I’m doing at Yahoo is documenting best practices for REST. Engineers there are smart, and will immediately ask what the benefit of a particular recommendation is, calling BS if there isn’t one. So, I have to justify every recommendation with tangible benefits. I’m still in-progress, but I hope to report some of the results when they’re more baked.
Ryan,
I agree with much of what you say, but how does Squid take advantage of PUT and DELETE today? I don’t think it retries them (taking advantage of idempotence). Also, there’s some debate of the idempotence of PUT, because WebDAV allows it to have side effects (creating a new revision). I believe DELETE can have side effects as well.
comment at 22. March 2006
Mark Baker:
I just didn’t know where to start, Ryan.
I also didn’t appreciate the characteriziation of my work as the “result of people who just can’t help but make architecture”, which motivated the terse (and, admittedly, unhelpful) response.
comment at 22. March 2006
Robert Sayre:
“the result of people who just can’t help but make architecture”
Hmm. Maybe that’s another example of the type of stuff that is a little too trollish. If we can piss each other off with that stuff, imagine how a C# developer who worked hard some SOAP thing must feel reading this site.
I guess it depends on whether we want people to adopt REST. If we want to reserve a space to feel smug and superior, it seems like we’re doing a great job.
comment at 22. March 2006
Ethan Fremen:
The main way in which the additional verbs are really helpful in an application is whenever you want to manipulate multiple resources at once. Of course, in most cases where you’re doing that, you’re using even more of those ‘useless’ verbs, like MKCOL and PROPFIND etc.
To me it’s like you’re arguing that the only methods anyone ever needs on a class are gettr and settr methods.
It is mostly true that the prettiness of the URLs is only germane to human memory, but sometimes that is quite relevant to your application.
comment at 23. March 2006
Paul James:
Ethan: You don’t need new verbs to manipulate multiple resources at once, you just need another resource that represents all the resources you want to manipulate together and to then manipulate that with your existing verbs.
comment at 25. March 2006