Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elasticsearch GET request with request body

Isn't it against REST-style approach to pass a request body together with GET request?

For instance to filter some information in Elasticsearch

curl localhost:9200/megacorp/employee/_search -d '{"query" : {"filtered" : {"filter" : {"range" : {"age" : { "gt" : 30 }}},"query" : {"match" : {"last_name" : "smith"}}}}}'

some tools are even designed to avoid request body in GET request (like postman)

like image 469
yurko Avatar asked Apr 29 '16 13:04

yurko


3 Answers

From the RFC:

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.

In other words, it's not forbidden, but it's undefined behavior and should be avoided. HTTP clients, servers and proxies are free to drop the body and this would not go against the standard. It's absolutely a bad practice.

Further text from the HTTPBis working group (the group working on HTTP and related standards):

Finally, note that while HTTP allows GET requests to have a body syntactically, this is done only to allow parsers to be generic; as per RFC7231, Section 4.3.1, a body on a GET has no meaning, and will be either ignored or rejected by generic HTTP software.

source

like image 127
Evert Avatar answered Oct 19 '22 02:10

Evert


No. It's not.

In REST, using POST to query does not make sense. POST is supposed to modify the server. When searching you obviously don't modify the server.

GET applies here very well.

For example, what would be the difference of running a search with:

GET /_search?q=foo

vs

GET /_search
{
  "query": {
    "query_string": {
      "query" : "foo"
    }
  }
}

In both cases, you'd like to "GET" back some results. You don't mean to change any state on the server side.

That's why I think GET is totally applicable here wether you are passing the query within the URI or using a body.

That being said, we are aware that some languages and tools don't allow that. Although the RFC does not mention that you can't have a body with GET.

So elasticsearch supports also POST.

This:

curl -XPOST localhost:9200/megacorp/employee/_search -d '{"query" : {"filtered" : {"filter" : {"range" : {"age" : { "gt" : 30 }}},"query" : {"match" : {"last_name" : "smith"}}}}}'

Will work the same way.

like image 39
dadoonet Avatar answered Oct 19 '22 02:10

dadoonet


You can use query parameter in an ElasticSearch GET request: just add source=query_string_body&source_content_type='application/json'

The url will look like the following:

http://localhost:9200/index/_search/?source_content_type=application/json&source={"query":{"match_all":{}}}

ref: https://discuss.elastic.co/t/query-elasticsearch-from-browser-webservice/129697

like image 44
王信凱 Avatar answered Oct 19 '22 01:10

王信凱