apollo-server
apollo-server copied to clipboard
http request timeout on queries
Versions involved - "apollo-server": "^2.19.2", "apollo-server-env": "^3.0.0", "apollo-server-express": "^2.25.2",
What is the suggested way of setting a shared timeout for queries? Is there a global way, a middleware or does this need to be done on the resolver?
Thanks!
I don't think we have specific advice on doing this. It would be interesting to hear what conclusions other users have come to!
I can think of three ways -
- on the socket
- on the response at the express level
- on the resolver level.
All have drawbacks. That I can't find consensus on it is quite odd.
I haven't been able to find consensus on it either. I currently have an apollo-server-express implementation behind an AWS API Gateway and I have been trying to figure out what is the best way to timeout a request before hitting the timeout on AWS's end. Writing an express middleware can do the trick but the response would not be as complete as leveraging a timeout on the resolver level.
@RichardWright would you be able to elaborate on drawbacks on the three approaches? I'm trying to figure out which one would be the best for our use case. Right now I'm having troubles terminating execution on a resolver (that is running an http call to underlying service or being queued by a limiter for a call to an underlying service) when a client disconnects or when a request timeout would be exceeded.
Closing the socket caused issues with our event listener and was disruptive to down stream clients with keep Alives
Closing the response (express level basically) caused lots of checking for null ‘res’ as it would try to return after sending the response. Made for complicated code.
Best case for us was to set the timeout on the resolver. You get a proper graphql error on top of full Flow control.
HI @glasser,
We were using connect-timeout + apollo-server-express and noticed a few similar issues as those in #5834.
What would be the best advice for setting timeouts on the server side? Socket timeouts was an approach that avoided Cannot set headers after they are sent to the client, but suffer from the problems described above by @RichardWright. I also noticed issues in calling my subgraphs from my gateway with the switch to make-fetch-happen (various ECONNRESET errors), and so we switched our fetcher back to node-fetch. For now I am considering removing the connect-timeout middleware and perhaps setting timeouts on the client, but any guidance would be appreciated!
As mentioned there, I think the best approach would be to improve graphql-js so that its execution is interruptible.
It would be great if apollo-server natively supports request timeout or atleast have recommendation (in their docs) on how to implement it with express.js.
NestJS's timeout interceptor example is pretty interesting and it works great with their graphql support, but not sure how they implemented without graphql-js interruptible execution support. Ex: https://github.com/nestjs/nest/blob/master/sample/01-cats-app/src/common/interceptors/timeout.interceptor.ts
Perhaps the NestJS timeout doesn't actually stop graphql-js execution from running, just returns an error in parallel to the client?
I've filed https://github.com/graphql/graphql-js/issues/3764 I don't think there's much for us to do here until that is fixed (which we could contribute to); once there's an API that can be used, we can reopen an issue about integrating properly with the new API.