GraphQL 是否会在发生故障时取消数据获取?

Is GraphQL cancelling data fetching in case of a failure?

我想了解 GraphQL 的 (Java) 实现是否足够智能,如果在执行其中一个提取程序期间抛出异常,则可以取消预定的数据提取?

一个例子是我 运行 一个查询来检索客户的所有订单。假设客户有 100 个订单。这意味着 GraphQL 应该进行 100 次调用来检索每个订单的详细信息,但在执行过程中有一次调用失败了——49 次请求已经成功,第 50 次失败,还有 50 次请求。 GraphQL 将中断正在进行的查询执行,并立即 return 向客户端发送错误消息。但它会不会进行剩余的 50 次调用?

不,它将继续进行剩余的 50 次调用,因为它是规范 here 所要求的,第 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.

但是它会告诉你订单50失败了,失败的原因。最后,您将得到类似于 JSON 的响应:

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

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

它必须调用 解析器函数 100 次,但这是否意味着 100 次网络调用由您决定。没有什么能阻止您在 1 个网络请求中批量加载所有 100 个(如果 API 允许)。

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

这只会在你抛出 AbortExecutionException 时发生,否则下一个节点将被正常处理。部分结果是 GraphQL 中的常态。一个错误的列表元素不会阻止所有其他列表元素的解析。作为 ,此行为由规范描述。

查询的执行方式完全掌握在您的手中。如果全部是同步的,并且您使用 AbortExecutionException 中断执行,则不会进行进一步的调用。如果您发送异步请求(通过返回 CompletionStage 例如 CompletableFuture),Java 中没有通用机制来中断这些任务。当您取消 CompletableFuture 时,它会 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,因为它允许取消传播和线程中断。您仍然需要以一种真正对中断做出反应的方式来执行您的任务。所以大部分工作都在你身上。