1. 44
  1. 8

    Interesting idea, but it’s too late and non-orthogonal. The benefit would only be there if people stopped using POST for big GETs and really, it’s redundant with GET, so it would be better to replace GET too if you could. People want there to be well defined methods and codes for everything, but the more specific the codes are, the less general; and the more general the codes are, the less well defined. It’s just a fundamental tradeoff.

    1. 7

      Why not just allow GET queries to contain body?

      1. 5

        GET is defined to be cacheable by URL, which risks messing up the results if there’s any cache involved.

        This spec adds an unprecedented feature of using request body as part of the cache key.

        It’s a new request type, because you can’t mess with the oldest most common request type on the web.

        1. 3

          Especially given that several servers and clients already let you do this, it’s just against spec.

          1. 3

            Which spec?

            RFC 7231 says it’s just undefined:

            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.

            1. 1

              Oh interesting. I guess I never looked into it but I had heard that.

              1. 1

                Well, Postel’s law would probably say it’s a bad idea in general, but if you control the backend it would be fine.

        2. 5

          How would the world of HTTP change if this memo were adopted? It seems we collectively abandoned semantic hygiene of this sort long ago. How long might it take for client and server implementors to include this new method? Is there any recent precedent for a major change like this?

          1. 4

            Mh, I think it just makes sense. :)

            1. 3

              I honestly think this is a bad idea, and that no body being allowed inside a GET request isn’t actually such a bad thing! The distinction between a GET and a POST is all about how the network middleware treats the request. So I always think that bodies being forbidden in a GET request is a part of the compromise we’re making in order to reduce our burden and dependence on the middleware. If your “query” is so large that you can’t fit it into a GET request, then I’d say its handling is an application-side concern and the network middleware shouldn’t be burdened with it.

              So, say you feel like you want to make 100kb GET requests. Then why not make a POST request that creates a query resource with an id, followed by a number of GET requests to that id. A potential way to support this workflow would be to store queries like this in a fast in-memory DB like Redis, so that the server receiving the initial POST can pass on the request body to the actual machine that will execute, as well as the one that will serve its result when the GET arrives.

              With the suggested QUERY method, now we’re putting this burden on the middleware, which now needs to consider how it should cache queries with very large bodies, or load balancers will have to remember that large query body, so that if the first server that’s been serving the GET request fails, it can retry the same request against another server.

              The point I’m trying to make is that the constraints on the size of a GET request is not a historical accident, the need to have a conservative limit on the size of the request is intrinsic to the problem. Put another way, if you ever feel bad about bending over backwards to accommodate the limitations of a GET request, you might want to consider that you are building a more robust solution.

              1. 3

                Looks like custom query is a new attack surface

                1. 3

                  How so? Isn’t this proposal just a way to standardize what we already do in some other ways?

                  1. 1

                    There are two major issues I can see:

                    1. developers will need to consider this continuously, and they already have issues ensuring that all verbs’ paths transit security controls
                    2. compensating/mitigating controls at the edge will need to consider this, and they’re notoriously bad at keeping up to date with standards.

                    The first is relatively straight forward: developers will now need to track a new verb that they have to make sure that all authentication, authorization, &c controls are applied. For frameworks that tend to have a single object/method per URL/route (endpoint), this is relatively straight forward: you can have a single entry point for the endpoints, and just detect if the new verb is being used to access it. For frameworks that tend to separate out endpoints, this means we need a new method, it needs to have all controls applied, tested, &c. It’s not a huge deal, but it’s often an edge case I see when working with developers, but also not too different from our current pain.

                    The second is more myriad; generally, depending on your devices, servers, security software, &c &c, you can have all sorts of odd interactions between these devices and the destined applications. For example, years ago many large venders had very strict rules for SQLi and XSS. So how would we bypass them? well, we’d just change GET or POST to Foo (or the like). At the time, several application servers would use heuristics for verbs to determine how they should be interpreted: if it had a body, it was a POST, if not, it was a GET. But how did this bypass edge controls? Well they also had heuristics: if they could determine what the verb was, they would apply rules, otherwise they would just pass it to the downstream application server. If you application server was reliant on the edge controls to block SQLi or XSS, you were in trouble. We’ve gotten much better about these sorts of things, but they can still lag significantly (HTTP/2 controls come to mind, or SCTP as a TCP replacement for data exfiltration, because many systems simply pass those along).

                2. 2

                  Seems reasonable enough. GraphQL clwould have a little bit aesthetically pleasing with this fifteen years ago, but no reason not to propose it now.

                  1. 1

                    An adjacent problem I’d like to see solved (or, please, if you have a better solution!) Is when my request parameters to the server are a deeply nested data structure rather than a single layer (i.e. x=1&y=2&z=3). Right now I’m stringify()ing JSON+base64 to get this between client and API but it’s cumbersome and not standardized.