我将使用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的设计方式?
答案 0 :(得分:1)
根据spec,一个GraphQL文档可以包含任意数量的操作,其中一个操作是query
,mutation
或{{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字段显式引用的实体是相当普遍的,但规范中并未禁止任何突变接受其他标识符作为输入。