I'm developing a new RESTful webservice for our application.
When doing a GET on certain entities, clients can request the contents of the entity. If they want to add some parameters (for example sorting a list) they can add these parameters in the query string.
Alternatively I want people to be able to specify these parameters in the request body. HTTP/1.1 does not seem to explicitly forbid this. This will allow them to specify more information, might make it easier to specify complex XML requests.
My questions:
- Is this a good idea altogether?
- Will HTTP clients have issues with using request bodies within a GET request?
If you really want to send cachable JSON/XML body to web application the only reasonable place to put your data is query string encoded with RFC4648: Base 64 Encoding with URL and Filename Safe Alphabet. Of course you could just urlencode JSON and put is in URL param's value, but Base64 gives smaller result. Keep in mind that there are URL size restrictions, see What is the maximum length of a URL in different browsers? .
You may think that Base64's padding
=
character may be bad for URL's param value, however it seems not - see this discussion: http://mail.python.org/pipermail/python-bugs-list/2007-February/037195.html . However you shouldn't put encoded data without param name because encoded string with padding will be interpreted as param key with empty value. I would use something like?_b64=<encodeddata>
.I'm upset that REST as protocol doesn't support OOP and
Get
method is proof. As a solution, you can serialize your a DTO to JSON and then create a query string. On server side you'll able to deserialize the query string to the DTO.Take a look on:
Message based approach can help you to solve Get method restriction. You'll able to send any DTO as with request body
Nelibur web service framework provides functionality which you can use
For example, it works with Curl, Apache and PHP.
PHP file:
Console command:
Output:
Google for instance is doing worse than ignoring it, it will consider it an error!
Try it yourself with a simple netcat:
(the 1234 content is followed by CR-LF, so that is a total of 6 bytes)
and you will get:
You do also get 400 Bad Request from Bing, Apple, etc... which are served by AkamaiGhost.
So I wouldn't advise using GET requests with a body entity.
Neither restclient nor REST console support this but curl does.
The HTTP specification says in section 4.3
Section 5.1.1 redirects us to section 9.x for the various methods. None of them explicitly prohibit the inclusion of a message body. However...
Section 5.2 says
and Section 9.3 says
Which together suggest that when processing a GET request, a server is not required to examine anything other that the Request-URI and Host header field.
In summary, the HTTP spec doesn't prevent you from sending a message-body with GET but there is sufficient ambiguity that it wouldn't surprise me if it was not supported by all servers.
IMHO you could just send the
JSON
encoded (ie.encodeURIComponent
) in theURL
, this way you do not violate theHTTP
specs and get yourJSON
to the server.