节点限制
若要通过架构验证,所有 GraphQL API 调用都必须满足以下� �准:
计算调用中的节点
下面两个示例显示如何计算调用中的节点总数。
-
简单查询:
query { viewer { repositories(first: 50) { edges { repository:node { name issues(first: 10) { totalCount edges { node { title bodyHTML } } } } } } } }
计算:
50 = 50 repositories + 50 x 10 = 500 repository issues = 550 total nodes
-
复杂查询:
query { viewer { repositories(first: 50) { edges { repository:node { name pullRequests(first: 20) { edges { pullRequest:node { title comments(first: 10) { edges { comment:node { bodyHTML } } } } } } issues(first: 20) { totalCount edges { issue:node { title bodyHTML comments(first: 10) { edges { comment:node { bodyHTML } } } } } } } } } followers(first: 10) { edges { follower:node { login } } } } }
计算:
50 = 50 repositories + 50 x 20 = 1,000 pullRequests + 50 x 20 x 10 = 10,000 pullRequest comments + 50 x 20 = 1,000 issues + 50 x 20 x 10 = 10,000 issue comments + 10 = 10 followers = 22,060 total nodes
速率限制
GraphQL API 限制不同于 REST API 的速率限制。
API 速率限制为什么不同? 使用 GraphQL,一个 GraphQL 调用可以替换 多个 REST 调用。 单个复杂 GraphQL 调用可能相当于数千个 REST 请求。 虽然单个 GraphQL 调用远远低于 REST API v3 速率限制,但对 GitHub 的服务器来说,查询的计算成本可能同� �高昂。
为了准确表示查询的服务器成本,GraphQL API 将� �据� �准化点数来计算调用的速率限制分数。 查询分数计入了父连接及其子连接上的第一个和最后一个参数。
- 公式使用父连接及其子连接上的
first
和last
参数预计算 GitHub 系统上的潜在负载,如 MySQL、ElasticSearch 和 Git。 - 每个连接都有自己的点值。 此点值与调用的其他点数相结合,计入总速率限制分数。
GraphQL API 速率限制为每小时 5,000 点。
请注意,每小时 5,000 点与每小时 5,000 个调用不同:GraphQL API 和 REST API 使用的速率限制不同。
注意:在我们观察开发者如何使用 GraphQL API 时,当前公式和速率限制可能会发生更改。
返回调用的速率限制状态
使用 REST API,� 可以通过检查返回的 HTTP � �头来检查速率限制状态。
使用 GraphQL API,� 可以通过查询 rateLimit
对象上的字段来检查速率限制状态:
query {
viewer {
login
}
rateLimit {
limit
cost
remaining
resetAt
}
}
-
limit
字段返回客户端在 60 分钟窗口期限内允许使用的最大客户端点数。 -
cost
字段返回计入速率限制的当前调用的点成本。 -
remaining
字段返回当前速率限制窗口中剩余的点数。) -
resetAt
字段返回当前速率限制窗口重置的时间,单位为 UTC 纪元秒。
在运行调用之前计算速率限制分数
查询 rateLimit
对象时会返回调用的分数,但运行调用时会计入限制。 为避免这种两难局面,可以在运行之前计算调用分数。 下面的计算结果与 rateLimit { cost }
返回的成本大致相同。
- 将完成调用中每个独有连接所需的请求数� 起来。 假设每个请求都将达到
first
或last
参数限制。 - 将数字除以 100,然后将结果四舍五入,获取最终的聚合成本。 这一步可使大数字规范化。
注意:调用 GraphQL API 的最低成本为 1,表示单一请求。
下面是一个查询和分数计算示例:
query {
viewer {
login
repositories(first: 100) {
edges {
node {
id
issues(first: 50) {
edges {
node {
id
labels(first: 60) {
edges {
node {
id
name
}
}
}
}
}
}
}
}
}
}
}
此查询需要 5,101 个请求才能完成:
- 虽然我们要返回 100 个存储库,但 API 必须连接到查看器的帐户一次才能获取存储库列表。 � 此,存储库的请求 = 1
- 虽然我们要返回 50 个问题,但 API 必须与 100 个存储库的每个库相连接,才能获取问题列表。 � 此,问题请求 = 100
- 虽然我们要返回 60 个� �签,但 API 必须与 5,000 个潜在总问题中的每个问题相连接,才能获取� �签列表。 � 此,� �签请求 = 5,000
- 总计 = 5,101
除以100,然后四舍五入就得到了查询的最终分数:51