HTTP defines a concept of METHODS on a resource URI.
METHOD URI ACTION HAS REQUEST BODY? HEAD /foo/ID EXISTS NO GET /foo/ID READ NO POST /foo CREATE YES PUT /foo/ID UPDATE YES PATCH /foo/ID UPDATE (partial) YES DELETE /foo/ID DELETE NO
The mapping of HTTP requests method to the Create, Read, Update, Delete (CRUD) model is one of convenience that can be considered a useful, but incomplete, memory aid. Specifically it misrepresents the meaning and purpose of POST. According to RFC 7231 POST “requests that the target resource process the representation enclosed in the request according to the resource’s own specific semantics”. This can, and often does, mean create but it can mean many other things, based on the resource’s requirements.
More generally, CRUD models the four basic functions of persistent storage. An HTTP API is not solely a proxy for persistent storage. It can provide access to such storage, but it can do much more.
Please note that while HEAD is recommended for checking for the existence of a resource, the corresponding GET should always be implemented too, and should return an identical response with the addition of a body, if applicable.
TODO: HEAD is weird in a bunch of our wsgi frameworks and you don’t have access to it. Figure out if there is anything useful there.
TODO: Provide guidance on what HTTP methods (PUT/POST/PATCH/DELETE, etc) should always be supported, and which should be preferred.
When choosing how to update a stored resource, PUT and PATCH imply different semantics. PUT sends a full resource representation (including unchanged fields) which will replace the resource stored on the server. In contrast, PATCH accepts partial representation which will modify the server’s stored resource. RFC 5789 does not specify a partial representation format. JSON-patch in RFC 6902 specifies a way to send a series of changes represented as JSON. One unstandardized alternative is to accept missing resource fields as unchanged from the server’s saved state of the resource. RFC 5789 doesn’t forbid using PUT in this way, but this method makes it possible to lose updates when dealing with lists or sets.
There can also be confusion on when to use POST or PUT in the specific instance of creating new resources. POST should be used when the URI of the resulting resource is different from the URI to which the request was made and results in the resource having an identifier (the URI) that the server generated. In the OpenStack environment this is the common case. PUT should be used for resource creation when the URI to which the request is made and the URI of the resulting resource is the same.
That is, if the id of the resource being created is known, use PUT and PUT to the correct URI of the resource. Otherwise, use POST and POST to a more generic URI which will respond with the new URI of the resource.
The GET method should only be used for retrieving representations of resources. It should never change the state of the resource identified by the URI nor the state of the server in general. RFC 7231 states GET is the primary mechanism of information retrieval and the focus of almost all performance optimizations..
HTTP request bodies are theoretically allowed for all methods except TRACE, however they are not commonly used except in PUT, POST and PATCH. Because of this, they may not be supported properly by some client frameworks, and you should not allow request bodies for GET, DELETE, TRACE, OPTIONS and HEAD methods.