
Ask HN: Using HTTP GET with request body - larryfreeman
We are doing a RESTful service that is non-public.  For a request that is read-only and potentially uses 20+ parameters, we are planning to implement it as a GET request that will pass these parameters in the body.<p>I have seen the well known announcement by Dropbox in 2015: https:&#x2F;&#x2F;blogs.dropbox.com&#x2F;developers&#x2F;2015&#x2F;03&#x2F;limitations-of-the-get-method-in-http&#x2F; and the response in Hacker News: https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=9133469<p>As I understand it, there are three potential issues with a GET with request body:<p>(1)  Not all servers will support this.<p>(2)  Not all tools will support this (POSTMAN added support this year: https:&#x2F;&#x2F;github.com&#x2F;postmanlabs&#x2F;postman-app-support&#x2F;issues&#x2F;131)<p>(3)  There is not yet a consensus on GET with request body.  (For example, is Dropbox still using a POST)<p>I am not finding too many recent statements about this, I wanted to open up the question here and see what the current opinions are.<p>I heard that ElasticSearch is using GET request parameters in the body.  It sounds like there are some who are against this approach:
https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;36939748&#x2F;elasticsearch-get-request-with-request-body<p>(1)  Does this make sense for a private server?  (The answer here seems to be yes -- unless I am missing something)<p>(2) Does this make sense in general?  If the tools needed support it, what is wrong with implementing a RESTful service that requires GET request parameters in the body?
======
amirathi
I'd recommend sticking to POST requests with body that fetches the data you
need. I know it's semantically odd because the POST request not creating a
"resource" on the server. But it's practically very useful as it'll work well
with client libraries, load balancers etc.

You can get some inspiration from GraphQL for your use case. All GraphQL
queries are POST requests with body specifying what data the client needs.

~~~
larryfreeman
Thanks! This is exactly what we have decided to do.

Cheers.

------
dmlittle
While there's nothing stopping you from doing so I would be wary about it.
Even though the service will be internal you might still need to use third-
party software/tools in the future that will be incompatible because of this.

For example, will you need to use a 3rd party request library? Will you need
to set up some sort of proxy (NGINX, HAProxy, etc.)? Will you need to use a
cloud load balancer (I'm not sure if they would send a request payload for GET
requests)?

For open-source solutions you might be able to fork them to add this behavior
but why do so to begin with? Is there a specific reason why you don't want to
use query parameters?

~~~
larryfreeman
At this point, we have tested all 3rd party request libraries that we will be
using. It is possible that DevOps could change start using a new one in the
future that would not support a GET request with body.

I agree that it is well worth keeping this in mind and checking on the state
of third party support.

Would you happen to know which popular 3rd party tools do not currently
support a GET with request body?

------
AnotherIdiot
If you need to have lots of query parameters (I'm assuming that's what you're
referring to) then something is wrong in your design. Start by dividing your
problem into simpler parts and go from there.

A dumb idea would be to encapsulate various options into a single query
parameter. Compressing query parameter's names and values and encoding them in
base64 (or some other base of your choice) might also help. But all of this
will just add tons of needless complexity to it.

Do you really _NEED_ 20+ query parameters?

I am curious, though. What are you actually trying to achieve here?

~~~
larryfreeman
The purpose of the service is data retrieval based on up to 2,000 ids where
the data retrieved can then be aggregated as a csv file. The current service
does one id at a time which prevents optimizing the retrieval. Allowing 20+
ids enables 20+ data items to be extracted in a single database retrieval call
instead of 20+ separate ones which is currently being done.

So, from my view, the question is whether it is better to use a GET with a
request body or use something such as a POST even though the request is read
only.

~~~
AnotherIdiot
Hrmm, I see. Using GET with a request body is undefined behavior as per RFC.
What this means is that there's a very high likelihood of things breaking in
the future, because each software vendor as their implementation. You'd
probably need to test the software you are using internally.

Can't you use a range for said ids? Like

GET /blah?from_id=0&to_id=2000

Or are these said ids distinct from each other, like

GET /blah?id1=v&id2=v&idN=v ...

until id2000?

If the latter is what you're dealing with then this looks like bad design,
IMHO. You might need to redesign this if possible, otherwise you'll be
building on a house of cards. It's just a matter of time.

~~~
larryfreeman
Each id is distinct so there is no way to list them other than to actually
list each id. Typically, this will be 200 ids that are alphanumeric and where
a range would include the wrong ones.

Based on the discussion here (thanks to everyone!), we have decided to use a
POST instead of GET. :-)

The reasoning is that while GET works fine now, there is always a chance that
it will not work in the future either because of security decisions by DevOps
or because of use of a third-party tool that does not support GET with request
body.

------
zzo38computer
I think that only request methods that can use a request body can use a
request body. (However, it is only private use, then might not matter.)

One alternative way is to use a different protocol rather than HTTP, if that
is applicable for your use. Another way is to make up a new LONG_GET method.

~~~
larryfreeman
As much as possible, we are trying to keep things simple and implement our
service in a standard way.

One suggestion was to use a POST instead. On the surface, it seems like a Get
with request body seems like such a straight forward approach that I am hoping
that this will eventually become standard.

As far as I can tell, the only argument against this approach is that it is
not standard. If it was a common approach and there was consistently 3rd-party
support, would there be a problem with this approach?

------
tomohawk
Convention should always be adhered to unless you have a really good reason
for not doing so. This is especially true for things like REST where
convention is the whole point.

------
icedchai
Keep it simple and just use a POST. Sure, you're read only, but using a
request body with a GET is "weird" and non-standard.

~~~
larryfreeman
Yes, that seems to be the alternative. That is what we probably will do if
there looks like a reasonable chance that devops will move to a 3rd party tool
that does not support GET with a request body.

------
fabioyy
RFC of http protocol allows body content on GET.

------
quickthrower2
Another idea. PUT the list of ids and get an ID to that “blob” and in a second
request do a GET with the blob ID.

------
echeese
I think you should be wary of doing this - it may do weird things with a cache

~~~
larryfreeman
I've heard this. I am clear why it is true. I would appreciate it if you could
explain. :-)

I'm not clear why using parameters in the GET request body would do weird
things with the cache but using parameters in the POST request body will not
hit these issues.

~~~
sethammons
In general: GET can have caching, POST should not. However, if you are dealing
with internal only systems, it doesn't really matter. Browsers and some tools
have optimizations and expectations around what can be done with different
HTTP verbs. Maybe your load balancer could see the same GET request and serve
a cached value (as long as it counts the body in its caching logic). If you
are not hoping to take advantage of GET caching, just stick with a POST.

