I am designing an API and I wonder if it is fine to send a JSON payload on a GET request?
In this other question Payloads of HTTP Request Methods, we can find according to this link:
- HEAD - No defined body semantics.
- GET - No defined body semantics.
- PUT - Body supported.
- POST - Body supported.
- DELETE - No defined body semantics.
- TRACE - Body not supported.
- OPTIONS - Body supported but no semantics (maybe in the future).
Does this mean that I should not send a GET request with a payload? Are there risks to do so?
- Like having some HTTP client libraries incapable of sending such a payload?
- Or my Java API code not being portable on certain application servers?
- Anything else?
I found out that ElasticSearch was using such a payload on a GET request:
$ curl -XGET 'http://localhost:9200/twitter/tweet/_search?routing=kimchy' -d '{
"query": {
"filtered" : {
"query" : {
"query_string" : {
"query" : "some query string here"
}
},
"filter" : {
"term" : { "user" : "kimchy" }
}
}
}
}
'
So if this popular libary does it and nobody complains, then perhaps I can do the same?
By the way, I would like to know if this is OK to mix queryString parameters and JSON payload? Exactly like this ElasticSearch query does. If so, are there rules so that we know which arguments should be queryString parameters, or payload parameters?
Here we can read: HTTP GET with request body
Roy Fielding's comment about including a body with a GET request.
Yes. In other words, any HTTP request message is allowed to contain a message body, and thus must parse messages with that in mind. Server semantics for GET, however, are restricted such that a body, if any, has no semantic meaning to the request. The requirements on parsing are separate from the requirements on method semantics.
So, yes, you can send a body with GET, and no, it is never useful to do so.
This is part of the layered design of HTTP/1.1 that will become clear again once the spec is partitioned (work in progress).
....Roy
Then I don't really understand why it is never useful, because it makes sense in my opinion to send complex queries to the server that wouldn't fit well on queryParam or matrixParam. I think ElasticSearch API designers think the same...
I am planning to design an API which can be called like that:
curl -XGET 'http://localhost:9000/documents/inbox?pageIndex=0&pageSize=10&sort=title'
curl -XGET 'http://localhost:9000/documents/trash?pageIndex=0&pageSize=10&sort=title'
curl -XGET 'http://localhost:9000/documents/search?pageIndex=0&pageSize=10&sort=title' -d '{
"someSearchFilter1":"filterValue1",
"someSearchFilter2":"filterValue2",
"someSearchFilterList": ["filterValue3","xxx"]
... a lot more ...
}
'
Does it seem fine to you? Based on the above considerations.