RESTful Web Services are all the rage. And there's little wonder why. They can be a simple way to exchange data with applications without all of the baggage that typically accompanies SOAP or RPCs. Yes, RESTful Web services are a wonderful thing. But if implemented incorrectly, they can be a very painful thing for both your applications and your users.
What Are RESTful Web Services?
RESTful Web Services were first described by Roy Fielding in his dissertation, "Architectural Styles and the Design of Network-based Software Architectures." In his dissertation, Fielding described a Representational State Transfer (REST) approach to Web services. He proposed using HTTP and it's methods to work with resources.
Unlike SOAP and earlier RPC (remote procedure call) methods, RESTful Web services really just describe resources. The actions requested are represented by the HTTP methods. For example, a GET method executed on a resource http://www.mywebsite.com/user/bob means get a representation of user bob. The resource is user bob and the method is get; it's as simple as that.
How It Gets Complicated
Most developers have heard of a GET request. After all, GET is the default method specified by most browsers when a resource on a website is requested. But most developers I know couldn't tell you even three other HTTP methods, let alone how they should be used. As a result, a common problem is that some developers try to use GET methods for everything.
So, what happens when you use a GET method to update the state of a resource? Well, for one thing, the GET method no longer functions as intended. The GET method is supposed to be idempotent. That means, subsequent calls using the GET method should not yield unexpected results. That makes sense when the GET method is used properly. Requesting a resource multiple times certainly won't change it's state or its representation. However, when you use GET to change something, that may no longer be the case.
The other problem with using GET methods for more that just requesting resources is that it no longer retains its meaning. Remember that REST is Representational State Transfer. That means the methods you use should actually represent what you are doing. When GET does double or even triple duty then it no longer is representational of what it does.
Aside from you looking like an idiot and having anyone using your crippled RESTful services wanting to beat you with their keyboard, using GET methods for things like resource creation can have some serious technical problems. For example, say you wanted to create a large PDF resource or even just a resource with a large value. GET methods are severely constrained in terms of how much data they can pass in the request. Typically, anything over 255 characters is considered pushing it, since some web servers might not support it. It's really just better to use the right method for the right job.
Using the Right Method for the Right Job
Below are a list of the available HTTP methods and how they can and should be used in the context of RESTful Web services.
As described above, GET methods are used to get resources. That's it!
POST methods are used to create new resources where none existed before. POST is not idempotent, which means that executing the same POST method more than once can cause more than one change to occur. An example is calling POST http://www.mywebsite.com/user with the body of the message specifying the details of the user resource.
PUT methods are typically used to change something in a resource. You can think of them as an update of sorts. An example would be calling PUT http://www.mywebsite.com/user/bob with the body of the message specifying the details of the user bob resource, complete with any updated fields.
PATCH methods are for partial updates. For example, let's say you only wanted to update the wearsGlasses attribute of user bob to true, but you either didn't know or didn't care to update any of user bob's other attributes. In that case you could do a PATCH with wearsGlasses set to true as the only data in the body of the request.
DELETE methods remove resources. As an example, DELETE http://www.mywebsite.com/user/bob would remove the user bob resource.
What About When I Want to GET a Resource?
One very common question (so, I might as well throw it in) is how should the application handle different GET request formats. Fortunately, there is a very simple answer: let the client determine the format.
For those of you looking at the screen cross-eyed, this idea is nothing new. Consider this, if you typed http://www.mywebsite.com/something.html then you would probably expect to get an HTML document returned. Why? Because you specified .html. So, it stands to reason that if you want an HTML representation of a response with REST, you should be able to specify something like http://www.mywebsite.com/user/bob.html. That should give you an HTML representation of user bob.
If you want an object representation of a resource using REST, the client should specify that too. For example, if you want user bob in XML format, then you should make the request with the Accept HTTP header set to ''text/xml." If you want the response in JSON, then just set Accept to "application/json." The service should be smart enough to return the correct format; frameworks like Spring MVC do that kind of thing automagically.