crystal icon indicating copy to clipboard operation
crystal copied to clipboard

HTTP GET method?

Open outsidenote opened this issue 8 years ago • 4 comments

We are seriously considering to start using postgraphql in our prod environment, however we have a concern regarding cache performance. Currently, from trying out the examples, we see that there is no support for GET requests.

From reading this I understand that HTTP GET requests are supported in the GraphQL protocol.

Is there a way to "turn on" GET requests support in postgraphql as well?

Thanks a lot!

outsidenote avatar Apr 16 '17 18:04 outsidenote

Since postgraphql can be mounted as an express middleware it should be relatively easy to mount it with a higher order function that translates a GET request into a POST request that postgraphql understands, e.g. (completely untested, off the top of my head):

const hackReq = (fn) => (req, res, next) => {
  if (req.method === 'GET') {
    req.method = 'POST';
    const payload = {
      query: req.query.query,
      operationName: req.query.operationName,
      variables: req.query.variables,
    };
    const originalBody = req.body;
    req.body = payload;
    fn(req, res, (err) => {
      req.body = originalBody;
      req.method = 'GET';
      next(err);
    });
  } else {
    fn(req, res, next);
  }
}
app.use(hackReq(postgraphql(...)));

You may have to do a little source diving to see exactly which request objects we rely on, but something along these lines should hopefully be sufficient to test your hypothesis that GET is required/brings significant advantages.

I expect a pull request would be welcome that enable GraphQL queries over GET requests.

benjie avatar Apr 16 '17 18:04 benjie

If being honest, I'll probably won't get around to implement that feature, as we are yet to commit to this project which makes it less of a dev priority in our organization.

However, if this feature should be implemented, we would reconsider this project as it is so elegant and appealing.

So, with that in mind, I'll try to explain why this feature brings significant performance advantages in some (common) cases in the hope that someone will rise to the challenge :)

Our API server resides behind a CDN service which caches GET requests for about 10 minutes per request. The caching is done per URL + query string + Authorization header. Granted, that caching is almost useless for API endpoints that require authorized access as each request is unique per user (such as viewing user account etc.). However we have 2-3 endpoints that are always used on application startup which do not require authorization and have the same URL + query string for large batches of requests. More than 90% of incoming requests are to those 2, and currently using REST endpoints, we have such a large cache hit rate that the majority of requests doesn't reach our servers.

As CDNs in general do not cache POST requests, using this method for the common endpoints (instead of GETs) would force us to quadruple our computing power just to serve the same traffic.

This scenario applies, I think, to all services that have large portions of traffic served anonymously (without login).

Hope I got my point across. Good luck with further development of these great project!

outsidenote avatar Apr 17 '17 07:04 outsidenote

I would also love to see GET request handling in postgraphql. Like @outsidenote already stated, GET support for GraphQL servers is recommended in the official docs.

sonovice avatar Jun 26 '17 18:06 sonovice

The workaround middleware above should work (untested); a pull request with tests to enable this in-core would be welcome.

benjie avatar Jun 26 '17 22:06 benjie

Fixed in V5; see: https://postgraphile.org/postgraphile/next/config#grafserv-options and the graphqlOverGET setting.

benjie avatar Oct 04 '23 18:10 benjie