GraphQL 是不是会在失败时取消数据获取?

Posted

技术标签:

【中文标题】GraphQL 是不是会在失败时取消数据获取?【英文标题】:Is GraphQL cancelling data fetching in case of a failure?GraphQL 是否会在失败时取消数据获取? 【发布时间】:2019-11-06 18:07:38 【问题描述】:

我试图了解 GraphQL 的 (Java) 实现是否足够智能,如果在执行其中一个提取器期间引发异常,则可以取消计划的数据提取?

例如,我运行一个查询来检索客户的所有订单。假设客户有 100 个订单。这意味着 GraphQL 应该进行 100 次调用以检索每个订单的详细信息,但在执行过程中,其中一个调用失败 - 49 个请求已经成功,第 50 个失败,还有 50 个请求要执行。 GraphQL 将中断正在执行的查询,并立即向客户端返回错误。但它会打剩下的 50 个电话吗?

【问题讨论】:

【参考方案1】:

这意味着 GraphQL 应该进行 100 次调用以检索每个订单的详细信息

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

GraphQL 将中断正在执行的查询,并立即向客户端返回错误。

只有当你抛出 AbortExecutionException 时才会发生这种情况,否则下一个节点将正常处理。部分结果是 GraphQL 中的常态。一个错误的列表元素不会阻止所有其他元素的解析。正如Ken Chan noted,规范描述了这种行为。

查询的执行方式在很大程度上掌握在您的手中。如果它都是同步的,并且您使用AbortExecutionException 中断执行,则不会进行进一步的调用。如果您调度异步请求(通过返回 CompletionStage,例如 CompletableFuture),Java 中没有通用机制来中断这些任务。当您取消CompletableFuture 时,它会does not interrupt the underlying thread。更疯狂的是,它甚至无法将取消传播到之前的CompletionStages。这是一个 Java 问题,根本不是 GraphQL 或 graphql-java 特有的。你必须想出非平凡的机器来实现这一点。一种方法可能是使用Tascalate Concurrent,因为它允许取消传播和线程中断。您仍然需要以一种对中断做出实际反应的方式来执行您的任务。所以大部分工作都在你身上。

【讨论】:

【参考方案2】:

不,它将继续进行剩余的 50 次调用,因为规范 here 要求它,第 3c 点:

返回一个列表,其中每个列表项都是调用的结果 CompleteValue(innerType, fields, 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 ]  
      
   ]

【讨论】:

可能我没有正确表达我的问题。如果 GQL 对整体响应没有任何影响,为什么还要进行剩余的 50 次调用?这些调用只会浪费资源。我看不出与规范的冲突。只是为了确保我清楚:查询是“获取 customerId=123 的所有订单”。它不是“获取所有 orderIds=[1,2,3,4,...] 的详细信息”。

以上是关于GraphQL 是不是会在失败时取消数据获取?的主要内容,如果未能解决你的问题,请参考以下文章

Apollo GraphQL 取消订阅似乎坏了

如何从 GraphQL 服务器获取平面数组作为响应

使用 Sequelize 从 MySQL 获取数据到 GraphQL 失败

GraphQL入门指南

在将 graphql-ws 客户端与 gqlgen golang 服务器连接时,获取到“ws://localhost:7080/query”的 WebSocket 连接失败

Oracle 11gR2 ORA-12638 身份证明检索失败解决方法