Let’s talk today about a quite interesting question related to the HTTP protocol. This question is: to be or not to be the body in HTTP GET request?
This question has been raised during the discussion about the search API. For the search API design there are such possible options:
- use a GET with payload
- use a GET with URL query parameters
- use a POST with payload
This article will be covering the first option, the other two options I’m going to cover in the next article.
Maybe not everyone knows but based on HTTP specification GET request can have a body the same as we get to see in the POST request.
The first version of HTTP called 0.9 included only one GET request method, no headers and request body are supported.
The client sends a document request consisting of a line of ASCII characters terminated by a CR LF (carriage return, line feed) pair.HTTP/0.9, 1991
then with RFC 1945 GET method was defined as:
The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI.HTTP/1.0, 1996 (RFC 1945)
so, the body is not a part of URI and should not be included in the request. But, newer RFC 7231 comes into play:
The GET method requests transfer of a current selected representation for the target resource.HTTP/1.1, 2014 (RFC 7231)
and GET method definition to become not so clear as the previous one, but the question with the body in request now is pretty clear:
A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.HTTP/1.1, 2014 (RFC 7231)
Clear, right. Or, not so clear? So, technically the body can be present but there is no guarantee that it will be processed correctly.
Moreover, there is a rule defined in RFC 2616:
A server SHOULD read and forward a message-body on any request; if the request method does not include defined semantics for an entity-body, then the message-body SHOULD be ignored when handling the request.HTTP/1.1, 1999 (RFC 2616)
Let’s try to look into the new RFC 7540 which is totally different, but I think it has one important moment.
This section shows HTTP/1.1 requests and responses, with illustrations of equivalent HTTP/2 requests and responses.
An HTTP GET request includes request header fields and no payload body and is therefore transmitted as a single HEADERS frame…HTTP/2.0, 2015 (RFC 7540)
So, considering all above the final decision is even if technically GET request could have a body, this is strongly not recommended to use GET with the body in request due to unpredictable result of request processing. You can read more about other options there.