RESTful API memo: PUT and POST verbs

Before designing a RESTful API, it can be useful to recall how the HTTP protocol works.

Maurizio Turatti
SoftInstigate Team
4 min readJan 23, 2018

--

PUT and POST verbs sometimes can be a source of confusion. Let’s briefly recap how they are supposed to work, by revisiting the Hypertext Transfer Protocol.

The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line.

In other terms, POST is meant to append to existing resources or incremental creations of subordinate resources. It’s a “kind request” to a server to perform an action:

The actual function performed by the POST method is determined by the server and is usually dependent on the Request-URI. The posted entity is subordinate to that URI in the same way that a file is subordinate to a directory containing it, a news article is subordinate to a newsgroup to which it is posted, or a record is subordinate to a database.

PUT instead is appropriate to handle one-shot operations, creating or replacing directly an entire resource.

The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI.

Abstract differences

Often the two verbs can be confused, but they have different meanings:

The fundamental difference between the POST and PUT requests is reflected in the different meaning of the Request-URI. The URI in a POST request identifies the resource that will handle the enclosed entity. That resource might be a data-accepting process, a gateway to some other protocol, or a separate entity that accepts annotations. 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.

Another remarkable difference is that PUT requests are required to be idempotent, while POST requests aren't:

Methods can also have the property of ‘idempotence’ in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request. The methods GET, HEAD, PUT and DELETE share this property. Also, the methods OPTIONS and TRACE SHOULD NOT have side effects, and so are inherently idempotent.

Repeating several times a PUT operation with the same input values must have exactly the same consequences as performing that operation one single time.

Idempotence doesn’t hold for POST operations, as the server usually needs to alter its internal state to handle these subordinate resources, so multiple consecutive POST requests, even with exactly the same input data, could accumulate side effects.

Concrete differences

Let’s say we’re accessing a database with a RESTful API on top of it: if we PUT a record or document, then the HTTP request should contain all the data and also the unique ID of the new record, which is a client-side decision: the server acts as a receiver of content entirely composed by the client. The server doesn’t (should not) alter the received data in any way but limits itself into storing it persistently.

On the other hand, a client executing a POST request usually expects the server to return at least the record’s unique ID, which is generated internally by the database (or the application). In this case, the server has to hold some internal state, for example a counter or unique ID. On this regards, the client delegates some decisions to the server, and these decisions can also alter the record’s content itself (if the server-side generated ID is also part of the created record or document, which is usually the case).

It’s worth noticing that the HTTP specifications don’t require servers to return any response in the body as the result of a PUT or POST request, or any write request in general. The HTTP protocol instead suggests the usage of the HTTP body for data and the HTTP headers for returning metadata, such as the “Location” or “ETag” headers.

References

--

--