PUT vs POST

To PUT or to POST? Amazing how often this simple decision can cause a major falling out. I’m currently designing a RESTful API; while reviewing progress my lead developer and I virtually came to blows. I won the argument by virtue of being prepared to stay later at work only to have him arrive the next day with five REST books marked at pages that would contribute towards the discussion.

First things first: broadly speaking, browsers do not support PUT. Therefore if you are developing something that will be accessed via a browser use POST in preference to PUT. This is not RESTful, it is pragmatic.

PUT can be used to either create or modify a resource, as can POST. The difference is that PUT acts on the resource directly whereas POST acts on some of a controller, or manager, that modifies the resource. Using either PUT Or POST we send a representation of the resource. Conceptually it’s easier to think about acting directly on the resource rather than through a proxy.

Generally, the response to PUT should be 201 Created followed by a location header to the location of the new resource; though there is no reason why you couldn’t return the new, or modified, resource. With POST you can return 201 Created or you could return 200 OK with a status message. With both you should return the location of the new resource either as a header or in the body of the response. Unlike PUT, the client has no way of knowing the location of the new resource.

The major advantage of PUT is scalability: it can be cached. PUT is an idempotent transaction meaning that if you do the same PUT more than once you will get exactly the same result. This means that the response from a PUT can be cached by a client or a proxy in the same way GET can be cached. To be fair, though, given the likelihood of multiple identical PUT requests this advantage turns out to be fairly small in practice.

To use PUT, the client must know the location of the resource. For an update the client already knows the resource location. To create a resource the client must either decide what to call the resource, and the server be agnostic regarding the name – think of a key-value store: the client sends a value and says store it as the key – or be privy to the rules regarding naming resources. Sharing these rules across the client server divide could not be considered either loosely correlated or a good thing. Alternatively it’s possible to set up a resource that would create a name from a series of parameters which the client would call to GET a name (unless there are too many parameters in which case the client would need to POST to the resource), the new resource could then be PUT to that location. This method would never be considered clear, elegant or pragmatic.

Considering the above, when creating a resource use POST in preference to PUT unless the client controls the names of new resources. If the client controls the names of new resources, use PUT to take advantage of caching.

When modifying a resource use PUT in preference to POST. Note that PUT does not need to send a complete representation of the resource. POST would be used to modify a resource if the modification is part of server process or if more than one resource is being modified.

  1. No comments yet.

  1. No trackbacks yet.