GraphQL:在一次网络调用中进行查询和变异

Edw*_*ang 4 github-api graphql

我将给出一个 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.
Run Code Online (Sandbox Code Playgroud)

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

因此,在一天结束时,我必须执行3 个API 调用来标记某些内容,而我本可以在 REST 中完成,而不是通过一次调用来完成。一般来说,我看到很多 GraphQL 突变 API 只在 ID 中进行交互(即使系统有其他可用的规范标识符),我最终不得不进行额外的往返。我做错了吗?或者这确实是 GraphQL 的设计方式吗?

Dan*_*den 5

根据规范,GraphQL 文档可以包含任意数量的操作,其中操作是querymutation或 之一subscription

\n\n
\n
    \n
  • 查询\xe2\x80\x93 读取\xe2\x80\x90only 获取。
  • \n
  • 突变 \xe2\x80\x93 写入后读取。
  • \n
  • 订阅 \xe2\x80\x93 一个长\xe2\x80\x90lived 请求,用于获取数据以响应源事件。
  • \n
\n
\n\n

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

\n\n

然而,在该操作中,可以请求任意数量的字段。因此,如果您需要两个或更多根级查询字段(通俗地称为“查询”),它们可能会集中在一个操作中:

\n\n
query ArbitraryOperationName {\n  getSomething\n  getSomethingElse\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

对于突变也是如此——你可以执行两个或多个突变(按顺序):

\n\n
mutation ArbitraryOperationName {\n  doSomething\n  doSomethingElse\n  doAThirdAction\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

因此,您需要将请求拆分为多个请求的唯一场景是:

\n\n
    \n
  • 您需要同时执行 aquerymutation-- 这些是单独的操作,因此必须单独发送它们。
  • \n
  • 您需要提供一个查询的部分结果作为另一个查询的输入。
  • \n
\n\n

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

\n\n
query {\n  repository(owner: "graphql", name: "graphql-js") {\n    label(name: "help wanted") {\n      id\n    }\n    issue(number: 100) {\n      id\n    }\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

也就是说,要求addlabelstolabelable您传递 ID 而不是标签名称,以及 ID 而不是问题/PR 的数字,这是 Github 的设计选择。虽然在突变参数中看到某种 id 字段显式引用的实体是相当常见的,但规范中没有任何内容禁止突变接受其他标识符作为输入。

\n