GraphQL:在一次网络调用中查询和变异
Posted
技术标签:
【中文标题】GraphQL:在一次网络调用中查询和变异【英文标题】:GraphQL: Query and mutate in one network call 【发布时间】:2019-10-21 04:51:46 【问题描述】:我将给出一个使用 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】:根据spec,GraphQL 文档可以包含任意数量的操作,其中操作是query
、mutation
或subscription
之一。
查询 - 只读获取。 mutation – 一个写入,然后一个提取。 订阅 – 一个长期存在的请求,用于获取数据以响应源事件。
对于一个特定的请求只能执行一个操作(如果提供了多个操作,则必须提供一个operationName
来指定要执行哪一个)。
但是,在该操作中,可以请求任意数量的字段。因此,如果您需要两个或多个根级查询字段(通俗地称为“查询”),它们可能会集中在一个操作中:
query ArbitraryOperationName
getSomething
getSomethingElse
突变同上——您可以执行两个或多个突变(按顺序):
mutation ArbitraryOperationName
doSomething
doSomethingElse
doAThirdAction
因此,您需要将请求拆分为多个请求的唯一情况是:
您需要同时执行query
和 mutation
- 这些是单独的操作,因此必须单独发送。
您需要提供一个查询的部分结果作为另一个查询的输入。
您应该能够在单个查询中同时获取标签 ID 和问题 ID:
query
repository(owner: "graphql", name: "graphql-js")
label(name: "help wanted")
id
issue(number: 100)
id
但是,您的变更必须是一个单独的请求,因为 1)它是一个不同的操作,并且 2)它需要作为上述查询返回的输入数据。
也就是说,addlabelstolabelable
要求您为标签传递 ID 而不是名称,为问题/PR 传递 ID 而不是数字这一事实是 Github 的设计选择。虽然在突变参数中看到由某种 id 字段显式引用的实体相当普遍,但规范中没有任何内容禁止突变接受其他标识符作为输入。
【讨论】:
以上是关于GraphQL:在一次网络调用中查询和变异的主要内容,如果未能解决你的问题,请参考以下文章
从 lambda 调用 AWS AppSync GraphQL API 变异查询
身份验证Apollo Graphql for android