< Reviews of Old Science Fiction Magazines: F&SF 1993/05
Request Weblog #Frog.Frog >

[Comments] (3) Request Weblog #Frog: REST Request: I wasn't going to get involved in the latest REST brouhaha because... well, because I've had to deal with nearly-identical brouhaha at work, and I'm kind of tired of it. But Rachel Chalmers asked for my thoughts, and I have a conference talk I need to start thinking about, so sure.

It looks like this is going to be a multi-part entry, so here is the single most important point I'd like to make. I mentioned it here, last year, and also mentioned it in RESTful Web Services (see especially pages 220-221), though not as prominently as I probably should've. Maybe I'll work this here into the second edition.

REST says you should use a uniform interface, but it doesn't say which one. How do you choose? You pick a set of verbs that 1) gives you the semantics you need for your application, and 2) lets you tie into network effects.

On one end there's the degenerate uniform interface of XML-RPC and SOAP: [POST]. Like a language with only one word, this is pretty useless. Seeing that "POST" gives you absolutely no information. POST means: "whatever!" You're just pushing the complexity somewhere else.

The one thing I want to say about this degenerate vocabulary is that your decision to use it is orthogonal to your decisions about resource design. XML-RPC and SOAP services provide a single "endpoint" resource, a monster message-processor at a single URL that responds to a wide variety of POST requests. That's bad resource design. But you could expose a tiny "message processor" for every part of your application you want clients to manipulate, and have them serve hypermedia documents (in response to POST) that linked these resources together. (See RWS page 303.) It would just suck, because clients could only communicate with those resources through POST.

Then there's the uniform interface of the human web: [GET POST]. Now that there are two verbs, you can give them separate meanings and split the complexity. GET means "read data" and POST means "change data." Actually, POST still means "whatever!" but since it's defined in opposition to GET, it's convenient to think of it as the opposite of GET.

Choose this set of verbs and you can perform a series of nifty optimizations on GET, which probably make up the bulk of your requests anyway. The GET optimizations work because GET means something. Its meaning is constrained, and constraints can be starting points for optimizations.

But, now that the words have real meanings, they can be misused. Use of GET where you mean POST will make you a victim of the next Google Web Accelerator type fiasco. Use of POST where you mean GET will ruin addressability and annoy your users.

And again, your decision about vocabulary is orthogonal to your decisions about resource design. Whence my rule of thumb: "POST to the same place you GET." If you had well-designed resources that responded to the degenerate vocabulary of [POST], you could convert your "read data" operations to GET and get a much better web service without changing your resource design. (again, see RWS page 303.)

Moving further down the scale of complexity is the uniform interface most often seen in discussions of REST: [GET POST PUT DELETE]. This vocabulary isolates certain classes of "change data" operations, rips them out of POST, and gives them their own names. POST still means "whatever!"

Why would we do this? Splitting out PUT and DELETE means giving them a meaning distinct from "whatever!" And a meaning is a set of constraints, and you can optimize around constraints, etc. Your decision to use this vocabulary is a decision about which constraints are useful.

And for the third time this is orthogonal to resource design. If you had a RESTful web service that used GET and POST for everything, you could PUTify any POST operations that fit the PUT constraints, DELETEify any operations that fit the DELETE constraints, and then you'd have a four-verb RESTful service. You could go the other way, too: fold PUT and DELETE back into POST and you'd have a RESTful two-verb service. What you'd lose is the ability to say, "make sure the state of the resource reflects the submitted document" or "make sure the resource goes away", instead of "whatever!"

A little more complex is the uniform interface we used throughout RWS. We use the same four verbs, but we told POST to stop meaning "whatever!" When we use POST, it's only allowed to mean "create a new resource underneath this one." We did this because "whatever!" is a linguistic rug under which to sweep things. If you write a book about home organization where you say "and here's how to sweep anything inconvenient under the rug!", readers will suspect that there are systemic flaws in your organization techniques. So we wrote a book where we organized complex things like queues and transaction systems without recourse to "whatever!"

But on a technical level, the point is not that "whatever!" is evil. The point is that if you chip a piece off "whatever!" and make it mean something specific, you can optimize around the constraints and reap the benefits. It's pretty clear from the history of the web that you need to separate "read data" out from "whatever!" Because there's less history, there's active disagreement about the cost/benefit tradeoffs of PUT, DELETE, PATCH, et al., though I find them very useful. But the vocabulary you use is an interoperability shibboleth, not a RESTfulness shibboleth.

Filed under:

Comments:

Posted by Asbjørn Ulsberg at Wed Aug 20 2008 03:10

Extremely well put. I couldn't in any way have said it better myself. I hope all REST advocates and opposers give this blog post a read.

Posted by John at Wed Aug 20 2008 07:55

Asbjørn, that should probably be "Extremely well POSTED," not "Extremely well PUT." :-)

Posted by Leonard at Wed Aug 20 2008 08:10

I PUT it a couple times after POSTing it to clean it up, so you're both right.


[Main] [Edit]

Unless otherwise noted, all content licensed by Leonard Richardson
under a Creative Commons License.