Is GraphQL cancelling data fetching in case of a failure?

Is GraphQL cancelling data fetching in case of a failure?


3

I am trying to understand if (Java) implementation of GraphQL is smart enough to cancel scheduled fetching of data if an exception is thrown during execution of one of the fetchers?

An example would be that I run a single query to retrieve all orders for a customer. Let’s say that the customer has 100 orders. That means GraphQL should make 100 calls to retrieve details for each order, but halfway during the execution one of the calls fail – 49 requests have already succeeded, 50th failed, 50 more requests to go. GraphQL will break the ongoing execution of the query and will immediately return an error to the client. But will it make the remaining 50 calls or not?

Share
Improve this question

3 Answers
3

Reset to default


3

That means GraphQL should make 100 calls to retrieve details for each order

It must call the resolver function 100 times, but whether that means 100 network calls or not is up to you. Nothing preventing you to batch-load all 100 in 1 network request (if the API permits it).

GraphQL will break the ongoing execution of the query and will immediately return an error to the client.

This only happens if you throw AbortExecutionException, otherwise the next node will get processed as normal. Partial results are the norm in GraphQL. One erroneous list element does not prevent all the others from resolving. As Ken Chan noted, this behavior is described by the spec.

How the query gets executed is very much in your hands. If it’s all synchronous, and you interrupt the execution with an AbortExecutionException, then no further call will be made. If you dispatch async requests (by returning a CompletionStage e.g. CompletableFuture), there’s no general mechanism in Java to interrupt those tasks. When you cancel a CompletableFuture, it does not interrupt the underlying thread. Even more insanely, it can not even propagate the cancellation to the previous CompletionStages. This is a Java problem, not GraphQL or graphql-java specific at all. You have to come up with non trivial machinery to enable this. One way would perhaps be to use Tascalate Concurrent, as it allows cancellation propagation and thread interruption. You still need to implement your tasks in a way to actually react to interruptions. So the bulk of the work is on you.

Share
Improve this answer


1

No , it will keep making the remaining 50 calls because it is required by the specification here ,point 3c :

Return a list where each list item is the result of calling
CompleteValue(innerType, fields, resultItem, variableValues)
, where
resultItem is each item in result.

But it will report to you that the order 50 is failed and its failure reason. At the end, you will get the JSON response similar to :

{
   "data" : {
     "orders" : [
         {"id" : 1 , ..... } , 
         {"id" : 2 , ..... } , 
         {"id" : 3 , ..... } , 
         ......
      ]
   },
   "errors" : [
      {
         "message" : "Fail to get this order details due to blablab..." , 
         "path" : [ "orders", 50 ]  
      }
   ]
}

Share
Improve this answer

1

  • Probably I didn't phrase my question correctly. Why does GQL have to make those remaining 50 calls if they will not have any impact on the overall response? These calls will by just a waste of resources. I can't see the conflict with the specification. Just to make sure I'm clear: the query is "get all orders for customerId=123". It is not "get details for all orderIds=[1,2,3,4,…]".

    – Rado Buransky

    Jun 25, 2019 at 17:16


0

@kaqqao Is there a solution for same problem statement but in ApolloServer (using typescript) ?

Share
Improve this answer

New contributor

user22360141 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

1



Not the answer you're looking for? Browse other questions tagged

or ask your own question.

Leave a Reply

Your email address will not be published. Required fields are marked *