Page 1 of 2
You probably should get a little uneasy when something becomes popular rapidly. It suggests that perhaps the popularity is all for the wrong reasons and so it is with REST - Representational State Transfer. So what is it? What are its limitations? Is it really so useful? Or is it just RESTrictive?
The first thing to say is that there is a lot of misunderstanding about what REST is. If you are a programmer in a hurry and just catch part of the conversation you might well decided that REST is trivial and fairly obvious - just use URLs to code remote procedure calls. This is 80% of REST but the remaining 20% is important and it is all a matter of how you organise the remote procedure calls.
Before going on it is important to say that you really don't have to agree to any of the following philosophy. It is, after all, fairly arbitrary. It all starts from the idea that the web is a really successful system and when implementing new systems we should try to emulate it. You could however decide that the web is a terrible system suitable only for the delivery of static pages and for a web app we need something more powerful. But for the sake of understanding REST let us first agree that the web is a good model of how thing should work and in any case fitting in with it brings many practical advantages.
If you take the "URLs are remote procedure calls" approach to web apps then you are free to invent as many commands or verbs as you like. For example, you could invent a scheme whereby:
in whatever serverside language you want to use. The method could do something like delete a record or return a query or whatever you wanted it to. The result could be returned to the client as HTML, XML, Jason or a form of your own devising.
There is a lot of freedom in this approach and indeed it is used as described by many standard systems implemented in PHP, Java, .NET or whatever language you prefer. The use of URLs to map to procedure calls is often referred to as "routing" but it is as old as CGI.
The REST API
This approach is mostly OK, but it does have its critics. However when you move to make a public or even private API out of your URL routing it starts to get messy. Actually even when you don't formalise your use of URLs to invoke methods it is still often messy it's just you don't need to look at the mess.
What REST does is attempt to put some structure on the way you use URLs both in terms of the resources i.e the nouns that you create and the commands i.e the verbs that manipulate the resources. Some programmers regard the full structure of REST as being just too constraining and they tend to use it as a guide rather than a set of design rules.
The first rule is that URLs only ever represent resources. This sort of makes sense in that a URL can be regarded as the address of some "thing".At this point we could examine the idea of a representation of a resource and much philosophy but lets assume that we are all programmers and we understand the idea or data representation.
So how do you encode the commands?
The second rule is that you encode commands only use the four fundamental HTTP operations - GET, PUT, POST and DELETE.
If there is a shock in the REST idea it is this.
The design principle that is being proposed is that that the web is great and as it really is so great we should try to work with what it works with and make our applications look like standard web transactions and that means HTTP verbs. The argument goes that the HTTP infrastructure knows how to handle these four verbs in terms of caching, authorization and so on. Why invent the wheel when its already round?
Of course you could argue that HTTP was designed to to a very simple job - after all the first version of HTTP only had GET - and it was extended in a fairly ad-hoc way to produce what we know today. Just because it works for web pages doesn't mean it is a perfect solution for web applications - but let's try and stick with the idea for a bit longer. It just might be that the existing infrastructure is inadequate for the job and the four verbs are just the primitive base for what you can build on top. Even so we should look at what the HTTP verbs are all about.
The HTTP verbs are very simple and it is reasonable to consider GET and DELETE first because they are particularly simple.
- A GET is what you use to get a page. You supply the URL within the GET and the web server retrieves the resource and sends to to you as the response.
- DELETE is like a GET in that you specify the resource in the URL but the server deletes it rather than returns it.
As this point most accounts of REST discuss the fact that GET and DELETE are Idempotent - that is repeating them more than once doesn't change anything. For example, if you issue a DELETE then after the command the resource if it existed or not no longer exists. Do the command a second time and the result is the same. Idempotence is a good thing - especially so when you have the possibility of multiple asynchronous updates. What you paid the bill more than once - no problem if it is an idempotent operation.
So far so good but if you look at any real web system you will find lots of examples where GET isn't idempotent. It is if you restrict your attention to getting simple static web pages but as soon as you allow dynamic pages repeated GETs to the same URL can have very different effects - just consider a page access counter to see that this is true. The most you can say is that in principle a GET should not modify the state of the system.
Now we move on to POST and PUT which is where the real confusion begins. Both can be used to send data with is intended to create or update an entity. They appear to do the same job and if you want to treat them as identical you can. There is nothing stopping you from doing a particular job either with a POST or a PUT. However the documentation suggests that there is a distinction - or rather you should aim to maintain the distinction.
- A POST is a request to submit the entity supplied to the entity specified by the URL. This may or may not result in a new entity being created.
- A PUT is a simple request to store the entity supplied under the URL specified.
To quote from the HTTP 1.1. spec:
"The URI in a POST request identifies the resource that will handle the enclosed entity....In contrast, the URI in a PUT request identifies the entity enclosed with the request -- the user agent knows what URI is intended and the server MUST NOT attempt to apply the request to some other resource. ..."
To my mind this is a small and almost philosophical difference and we would be just as well off if PUT was dropped from the protocol and POST looked after saving the entity under the specified name by way of a default handler say. Semantically the distinction seems to be unhelpful but notice that PUT is idempotent, i.e. PUTing the same resource more than once has the same effect as doing it just once.