Representational State Transfer (REST) is the explicit architecture of HTTP and the World Wide Web. It is a well-designed, well thought out system that enables scalable applications that service millions of users. It is also a simpler system that enables developers who understand it to bring applications to market faster that perform better. Well, actually, no, it’s not. And therein lies a story.
HTTP is based on four basic operations: GET, PUT, POST, and DELETE.
- GET is used for safe operations: ones without any side effects. GETable operations can be completely specified by the URL and can be bookmarked, linked to, prefetched, cached, and otherwise optimized.
- POST is used for unsafe operations: ones that cause things to happen. You can’t even use the back button on a post without seeing a warning. For example, pressing the buy button in an online store should be a post because it causes the credit card to be charged. Pushing the buy button twice, causes you to be charged twice. That’s unsafe and shouldn’t be done by a machine without a human decision. Furthermore, a lot of the data for a POST request is actually encapsulated in the the HTTP request body, not in the URL as with a GET. Thus POST operations cannot be bookmarked, linked to, prefetched, cached, and otherwise optimized. However, POST is the most general method and can be used for almost anything.
- PUT is used to create or update a resource at a specific URL. PUT is not safe (it changes or creates a new resource) but it is idempotent. That means that if you aren’t sure if a request succeeded, try it again. PUTting the same content twice is not a problem. The end result is the same as PUTting it once. By contrast, POSTing a form twice might mean you’ve bought two copies of Oops!… I Did It Again (and one’s embarrassing enough).
- Finally DELETE is the simplest method. It deletes the resource at a specified URL. It too is idempotent, since deleting a previously deleted resource has no effect.
The beauty of REST is that those four verbs are all you need. Everything you need to do can be done with GET, PUT, POST, and DELETE. You don’t need to invent a new verb for every operation you can imagine. This make HTTP scalable, flexible, and extensible. Simplicity leads to power.
The problem is that GET, PUT, POST, and DELETE really are a minimal set. You truly do need all four, and we only have two; and I’ve never understood why. In 2006 browser vendors still don’t support PUT and DELETE. A few browsers over the years have tried to implement these as parts of editing functionality, but they’ve never allowed it in a real web application as opposed to a thick client GUI. The
method of an HTML form is limited to GET and POST. PUT and DELETE are not allowed. This isn’t some failure of browser vendors to properly implement the specification either. The HTML specification only allows GET and POST as form actions. XHTML and even XForms 1.0 don’t change this. This means it’s impossible to build a fully RESTful client application inside a web browser. Consequently everyone tunnels everything through POST, and simply ignores PUT and DELETE.
I’m getting really tired of explaining REST to people, and then having to back off and say, “This doesn’t actually work yet, and there doesn’t seem to be a possibility of it working in the near future.” Why do we have to tunnel everything through POST? Why don’t HTML forms support PUT and DELETE? I’d understand it if the browser vendors had simply failed to implement the spec. Lord knows they’ve ignored enough other things in the past. But that’s not the case. Even XForms 1.0 restricted itself to GET and POST, because, hard as it is to believe, the working group couldn’t think of any use-cases for PUT and DELETE!
Fortunately, the REST train may finally be leaving the station, even if it’s years late. XForms 1.1 will allow DELETE and PUT as form actions. No mainstream browsers have yet implemented even XForms 1.0, but maybe we’ll be able to use them sometime before I retire.
If you don’t want to wait that long, you can roll your own with AJAX. It’s easy enough to set the method of an
open call to PUT or DELETE:
var request = new XMLHttpRequest(); request.open("DELETE", "http://www.example.com/foo/bar.html", true);
At this point you’re halfway to rolling your own thick client GUI, but at least you can deploy it inside a web browser.
If you are rolling your own thick client GUI, then your options open up a little, as long as you use an HTTP library with full support for PUT and DELETE such as the Apache HttpClient 3.0. Even java.net.HttpURLConnection will do in a pinch; and if worst comes to worst, you can always roll your own on top of raw sockets.
Of course, then you have to worry about the server side. The support is once again not as ubiquitous as it should be, but it’s a lot better than on the client. All major web servers accept PUT and DELETE requests, and most recent versions of web app frameworks like the Java Servlet API or PHP also do. Some older versions have problems, but it’s easier to upgrade your server than everybody’s client. You may have to tell the server how to handle a PUT or DELETE request, just as you have to tell it how to handle a POST. In the future, I’d like to see mainstream servers treat PUT and DELETE more like GET: that is, support them out of the box with a little basic configuration rather than requiring a script to tell them how to handle it. POST needs a script because a POST can mean almost anything, but PUT and DELETE shouldn’t require the webmaster to set up more than a simple configuration and some user names and passwords.
However, it really is the client side, that’s the problem. Right now the best option for client-side PUT and DELETE seems to be to hook up a some