上周是我第一次涉足GraphQL,使用GitHubGraphQLAPI端点。我现在有意见了TM。
承诺非常棒:查询您需要的一切,仅此而已。一口气搞定。
但现实有些……不同。
我发现,您最终会得到大量垃圾数据结构,这些数据结构在客户端需要解密和处理、拆包边、节点等等。我最终不得不对返回的数据执行近一打array_column()、array_map()和array_reduce()操作以获得结构我真的可以使用。
我需要的最终数据如下所示:
[
{
"name": "zendframework/zend-expressive",
"tags": [
{
"name": "3.0.2",
"date": "2018-04-10"
}
]
}
]
要获取它,我需要如下查询:
query showOrganizationInfo(
$organization:String!
$cursor:String!
) {
organization(login:$organization) {
repositories(first: 100, after: $cursor) {
pageInfo {
startCursor
hasNextPage
endCursor
}
nodes {
nameWithOwner
tags:refs(refPrefix: "refs/tags/", first: 100, orderBy:{field:TAG_COMMIT_DATE, direction:DESC}) {
edges {
tag: node {
name
target {
... on Commit {
pushedDate
}
... on Tag {
tagger {
date
}
}
}
}
}
}
}
}
}
}
这给了我如下数据:
{
"data": {
"organization": {
"repositories: {
"pageInfo": {
"startCursor": "...",
"hasNextPage": true,
"endCursor": "..."
},
"nodes": [
{
"nameWithOwner": "zendframework/zend-expressive",
"tags": {
"edges": [
"tag": {
"name": "3.0.2",
"target": {
"tagger": {
"date": "2018-04-10"
}
}
}
]
}
}
]
}
}
}
}
我是如何发现如何创建查询的?我想说这是通过阅读文档。我真的会。但这些给了我几乎零个有用的例子,特别是涉及到分页、排序结果集,或者那些不同的“节点”和“边缘”位是什么,或者为什么它们是必要的。(我最终找到了这些信息,但作为最终用户,它仍然相当不透明。)
此外,看到pageInfo位了吗?这让我想到了下一点:分页很糟糕,尤其是当它不在顶层时。您一次只能从GitHubGraphQLAPI中的任何给定节点获取100个项目,这意味着分页。而且我还没有找到一个客户端可以检测结果中的分页数据并自动关注它们。此外,“after”属性必须是有效的……但没有示例说明什么是有效值。我不得不求助于StackOverflow来查找示例,但我仍然不明白它为什么有效。
我明白为什么客户端无法展开分页,因为分页数据可能出现在查询中任何地方。然而,这让我很受打击,因为我以为我有一套完整的数据,但在我最终正确处理后才发现大约一半丢失了。
我明白为什么客户端无法展开分页,因为分页数据可能出现在查询中任何地方。然而,这让我很受打击,因为我以为我有一套完整的数据,但在我最终正确处理后才发现大约一半丢失了。
如果树下的任何项目也需要分页,那么您将非常头疼,因为您必须深度优先获取分页集。
因此,虽然GraphQL承诺更少的往返次数和您需要的数据,但我目前的经验是:
-
我最终不得不非常小心地构建我的查询,非常注意分页潜力,并且经常无论如何发送多个查询。文档齐全的RESTAPI通常更容易理解和立即使用.
-
我最终在客户端做了更多工作,以使我收到的数据有用。这是因为有效负载结构基于查询结构和您需要的各种排列为了得到你需要的数据。同样,RESTAPI通常有一个单一的、记录良好的有效负载,使消费更容易。
我确定我可能误用了GraphQL,或者遗漏了一些使这些事情变得更容易的功能,但到目前为止,我只希望我可以拥有一些我可以始终如一地使用的有用的REST端点以便汇总我需要的数据。
在有人提出建议之前,是的,我非常知道GitHub还提供了RESTAPI,并且v3API具有满足我大部分需求的端点。然而,我不得不依赖标签,而不是发布,因为并非我们所有的标签都有关联的发布。但是,为标签返回的数据不包括提交日期;为此,您需要获取关联的提交,然后可能在
author或committer下获取日期。这种方法实际上意味着要进行数千次调用才能获取我需要的数据,这会使我达到速率限制,并且可能需要数小时才能完成。我的观点:也许不是GraphQL,而是聚合更多的数据在REST资源中(例如,包括带有标签的提交数据),或提供允许合并特定资源类型的端点可以轻松解决问题。这就是让开发人员关系团队找出消费者需要什么数据的地方派上用场,而不是简单地强制graphqlallthethings以允许无限的灵活性(以及这种灵活性的挫败感,对于API开发人员和消费者而言)。
在有人提出建议之前,是的,我非常知道GitHub还提供了RESTAPI,并且v3API具有满足我大部分需求的端点。然而,我不得不依赖标签,而不是发布,因为并非我们所有的标签都有关联的发布。但是,为标签返回的数据不包括提交日期;为此,您需要获取关联的提交,然后可能在
author或committer下获取日期。这种方法实际上意味着要进行数千次调用才能获取我需要的数据,这会使我达到速率限制,并且可能需要数小时才能完成。我的观点:也许不是GraphQL,而是聚合更多的数据在REST资源中(例如,包括带有标签的提交数据),或提供允许合并特定资源类型的端点可以轻松解决问题。这就是让开发人员关系团队找出消费者需要什么数据的地方派上用场,而不是简单地强制graphqlallthethings以允许无限的灵活性(以及这种灵活性的挫败感,对于API开发人员和消费者而言)。
更新
- 2018-09-19:语法高亮修复。
