我试图了解GraphQL的(Java)实现是否足够聪明,如果在执行其中一个提取程序期间引发异常,则可以取消计划的数据提取?
一个例子是,我运行一个查询来检索客户的所有订单。假设客户有100个订单。这意味着GraphQL应该进行100次调用以检索每个订单的详细信息,但是在执行的一半途中,调用之一失败-49个请求已成功,第50个失败,还有50个请求继续执行。 GraphQL将中断正在进行的查询,并将立即向客户端返回错误。但是它会打剩下的50个电话吗?
答案 0 :(得分:2)
这意味着GraphQL应该拨打100次以检索每个订单的详细信息
它必须调用 resolver函数 100次,但这取决于100次网络调用。没有什么可以阻止您将所有100合1的网络请求批量加载(如果API允许的话)。
GraphQL将中断正在进行的查询,并将立即向客户端返回错误。
这仅在您抛出AbortExecutionException
时发生,否则下一个节点将被正常处理。部分结果是GraphQL中的标准。一个错误的列表元素不会阻止所有其他元素解析。作为Ken Chan noted,此行为由规范描述。
如何执行查询完全掌握在您手中。如果它们都是同步的,并且您用AbortExecutionException
中断了执行,则不会进行进一步的调用。如果您调度异步请求(通过返回CompletionStage
,例如CompletableFuture
),则Java中没有通用的机制来中断这些任务。取消CompletableFuture
时,它does not interrupt the underlying thread。更疯狂的是,它甚至无法将取消传播到先前的CompletionStage
。这是一个Java问题,根本不是GraphQL或graphql-java所特有的。您必须提出一些非常规的机制才能实现这一目标。一种方法可能是使用Tascalate Concurrent,因为它允许取消传播和线程中断。您仍然需要以实际对中断做出反应的方式来执行任务。因此,大部分工作都在您身上。
答案 1 :(得分:1)
否,由于规范here要求,点3c:
,它将继续进行其余的50次呼叫。返回一个列表,其中每个列表项都是调用的结果 CompleteValue(innerType,字段,resultItem,variableValues),其中 resultItem是结果中的每个项目。
但是它将向您报告订单50失败及其失败原因。最后,您将获得类似于的JSON响应:
{
"data" : {
"orders" : [
{"id" : 1 , ..... } ,
{"id" : 2 , ..... } ,
{"id" : 3 , ..... } ,
......
]
},
"errors" : [
{
"message" : "Fail to get this order details due to blablab..." ,
"path" : [ "orders", 50 ]
}
]
}