GraphQL:在一个网络呼叫中进行查询和变异

时间:2019-06-05 16:27:21

标签: graphql github-api

我将使用GitHub GraphQL API给出一个特定的示例(这是我要解决的特定问题),但该问题似乎通常可以推广到GraphQL。

假设我要为存储库pytorch / pytorch上的问题#1234添加标签“高优先级”。根据API文档,我应该使用突变https://developer.github.com/v4/mutation/addlabelstolabelable/输入要求:

labelIds ([ID!]!)
The ids of the labels to add.

labelableId (ID!)
The id of the labelable object to add labels to.

好的,如何获取ID?在我的代码中,我知道我想要标签“高优先级”,但实际上将此信息传达给此突变,我必须首先将“高优先级”解析为一个ID,但首先要进行另一个GraphQL调用。我要标记的内容也是如此:我有一个唯一的标识符,形式为pytorch / pytorch#1234,但是我没有ID,必须查找它。)

因此,到最后,我必须做三个 API调用才能标记某些东西,而我本可以在REST中完成它,而只需一个调用。总的来说,我看到许多GraphQL变异API仅以ID进行对话(即使系统中还有其他规范的标识符可用),最终我不得不进行额外的往返。我做错了吗?还是这真的是GraphQL的设计方式?

1 个答案:

答案 0 :(得分:1)

根据spec,一个GraphQL文档可以包含任意数量的操作,其中一个操作是querymutation或{{1 }}。

  
      
  • 查询–只读获取。
  •   
  • 变异–先写后抓取。
  •   
  • 订阅–响应源事件而获取数据的长期请求。
  •   

对于特定请求,只能执行一项操作(如果提供了多个请求,则必须提供subscription来指定要执行的操作)。

但是,在该操作中,可以请求任意数量的字段。因此,如果您需要两个或多个根级查询字段(俗称“查询”),则可以将它们合并到一个操作中:

operationName

同上突变-您可以依次执行两个或更多个突变:

query ArbitraryOperationName {
  getSomething
  getSomethingElse
}

因此,唯一需要将请求拆分为多个请求的方案是:

  • 您需要同时执行mutation ArbitraryOperationName { doSomething doSomethingElse doAThirdAction } query -这些操作是独立的,因此必须分别发送。
  • 您需要提供一个查询的部分结果作为对另一个查询的输入。

您应该能够在单个查询中同时获得标签ID和问题ID:

mutation

但是,您的突变将必须是一个单独的请求,因为1)这是一个不同的操作,并且2)它需要作为上述查询返回的输入数据。

也就是说,query { repository(owner: "graphql", name: "graphql-js") { label(name: "help wanted") { id } issue(number: 100) { id } } } 要求您传递ID而不是标签名称和ID /而不是问题/ PR的数字,这是Github的设计选择。虽然在突变参数中看到某些id字段显式引用的实体是相当普遍的,但规范中并未禁止任何突变接受其他标识符作为输入。