Server Request Cancellation

Hey everyone, long time no see! (I helped maintain the Apollo devtools at one point, joined Google, then wasn’t able to help contribute as much due to their OSS policies, but now I’m at a start up!)

Background: Our GraphQL server is served from a Next.js API route using apollo-server-micro with a schema built using Nexus GraphQL. It’s pretty much copied from the Nexus docs.

It’s very common for our clients to cancel in-flight requests and try again a few seconds later. Is it possible to stop a query that’s already being executed when a request is canceled?

Thanks!

1 Like

Hello! I checked with the team, and it looks like the short answer is no, there’s nothing built into Apollo Server for terminating resolution of an in-progress operation.

I’ve created this issue on the apollo-server repo if you’d like to follow it.

As for a stopgap solution, if you have access to each client connection’s status, your most “expensive” resolvers could check that status before beginning their execution. If the connection has been terminated, they could update the shared resolver context with a connectionCanceled boolean and return null. Then, all of your resolvers could check for the presence of context.connectionCanceled and immediately return null if it’s present.

2 Likes

Thanks for opening that issue, @StephenBarlow.

A more complete answer of what an Apollo Server “feature” might look like here is not disjunct from what solving this would look like in a general sense in JavaScript — e.g., how would you stop functionality in the browser? – where you might have looping code check the truthiness of some sort of boolean state in order to determine if it should continue looping. There might be some affordances that we could build into Apollo Server for this – for example, preventing additional resolvers which haven’t fired off yet from starting, but generally speaking, terminating execution of a request once it starts will require implementors to offer yield-points within their business logic that checks for, e.g., a stop-like property. In precisely that spirit, the suggestion that @StephenBarlow offered to — e.g., — use a connectionCanceled property stored on the context, will probably get you most of the way to what you’re trying to accomplish.

1 Like

Thanks for the help! We implemented something exactly like this for each field resolver using Nexus’s plugin system. Works well in staging, will let you know how it works in prod.

@abernix yea I’m definitely not looking for a general JS stopping mechanism, just something to stop resolving the graph when the request is cancelled and throwing away the result rather than trying to validate it.

1 Like