Using HTTP methods in a REST service
In a normal language like English we use verbs all the time to describe what we are doing. So I guess the designers of the HTTP specs must have thought why not do the same with the HTTP protocol. And that makes perfect sense. In the HTTP spec these are called methods but commonly these are also names verbs. For example when we are using a browser to display some data from the Internet we are getting that data so we use the GET method. And as most of the time we are just retrieving data it makes sense that the GET method is very popular and used rather a lot. However we don’t just get data, sometimes we go to some web shop, for example http://www.amazon.com/, and want to buy something. In that case wee need to let the website know what books we want to order. In the browser we tend to use a POST method to indicate we are sending some data to the website.
When REST came along and it embraced the HTTP standard is also embraced the HTTP verbs. And it turns out that makes perfect sense because REST is about resources. And with resources we can do things like create retrieve, update or delete them. Sounds familiar? It should because these CRUD operations are very familiar to developers working with databases, the most common way of storing business data. Not that HTTP methods are limited to CRUD operations, the HTTP specifications defines a list of them here. And this list isn’t fixed, you are free to create your own HTTP methods as needed.
If we look under the hood we can see that the HTTP method is part of the HTTP header of the request being send to the server.
What about SOAP messages?
The SOAP standard uses HTTP as just one of many different possible ways of calling services. As a result it doesn’t really use HTTP methods. Sure if a SOAP message is send over an HTTP connection it requires an HTTP method but it will always use the POST method, even if it is just retrieving some data.
Now using just the POST method works just fine, after all we have been doing services with it for years, but there are a few drawbacks. For one the web has a lot of caching infrastructure build into it and using that we can greatly improve the scalability of our services. However POST is never cached so if we only use the POST method we completely ignore the available HTTP caching. There are several HTTP methods that allow for caching but GET is by far the most common of these. And it even allows both the service and the client control over the caching of data. In fact in the HTTP headers above we can see two additional headers, the If-None-Match and If-Modified-Since, used for cache control. But more about those in another blog post.
What HTTP method to use when?
The first thing to consider when choosing an HTTP method is if the action is safe. A safe action is something that doesn’t have any effects on the server. So retrieving data is a safe action because the current state is just returned. However updating data isn’t because that changes the state of the resource. Typically a safe action is done with an HTTP GET.
The next thing to look at is the action idempotent. An idempotent action will produce the same result even if it is repeated several times. A safe action is idempotent by its very nature, after all it doesn’t change anything. Some actions that change the state of a resource can also be idempotent. For example deleting some data a second time should be fine, the resource was supposed to be removed after the request and it is. Of course you have to be careful in writing your service in such a way that deleting the same resource twice doesn’t cause a runtime error. As expected this is normally done using the HTTP DELETE method
Another idempotent action is an update with the complete new state. After all if the request is processed twice all we would have done is repeat the same update. Be careful though, sending an update setting the number of books orders to 2 is an idempotent action but adding 1 to the current amount on order isn’t. Repeating the first action would still result in 2 books being ordered but repeating the second would result in 3 books being ordered. Updating the status of a resource is typically done with an HTTP PUT method.
In some cases the client doesn’t send all the data to the service, just the updated parts. In that case the it is suggested that you use an HTTP PATCH, or the similar Microsoft HTTP MERGE version, method to indicate that the data send doesn’t replace the complete resource but should be merged with it.
The final actions are not idempotent and as a result are the hardest to deal with. These actions typically add resources to the service, just like a SQL INSERT creates a new record, and repeating the same action would result in multiple resources being created. These actions are usually done using an HTTP POST method.
So basically our common CRUD actions map very well to HTTP methods:
- Create = POST
- Read = GET
- Update = PUT or MERGE
- Delete = DELETE
Of course there are more HTTP methods, the list is not limited to the predefined ones. So feel free to use additional ones as you see feel is appropriate.