节点限制
要通过模式验证,所有 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 为每个查询分配积分,并限制您在特定时间内可以使用积分的数量。此限制有助于防止滥用和拒绝服务攻击,并确保 API 对所有用户都可用。
REST API 也具有单独的主要速率限制。有关详细信息,请参阅“REST API 的速率限制”。
一般来说,您可以根据您的身份验证方法计算 GraphQL API 的主要速率限制
- 对于用户:每用户每小时 5,000 积分。这包括使用个人访问令牌进行的请求,以及 GitHub App 或 OAuth App 代表授权该 App 的用户进行的请求。由 GitHub Enterprise Cloud 组织拥有的 GitHub App 代表用户发出的请求具有更高的速率限制,每小时 10,000 积分。同样,如果您是 GitHub Enterprise Cloud 组织的成员,则由 GitHub Enterprise Cloud 组织拥有或批准的 OAuth App 代表您发出的请求每小时具有 10,000 积分的更高速率限制。
- 对于不在 GitHub Enterprise Cloud 组织上的 GitHub App 安装:每安装每小时 5,000 积分。拥有超过 20 个存储库的安装程序每小时会额外获得 50 个积分(每个存储库)。对于拥有超过 20 个用户的组织上的安装,每小时还会额外获得 50 个积分(每个用户)。速率限制不能超过每小时 12,500 个积分。用户访问令牌(与安装访问令牌相对)的速率限制由用户的 primary rate limit 决定。
- 对于 GitHub Enterprise Cloud 组织上的 GitHub App 安装:每安装每小时 10,000 积分。用户访问令牌(与安装访问令牌相对)的速率限制由用户的 primary rate limit 决定。
- 对于 OAuth App:每小时 5,000 积分,如果 App 由 GitHub Enterprise Cloud 组织拥有,则为每小时 10,000 积分。这仅适用于 App 使用其客户端 ID 和客户端密钥请求公共数据的情况。OAuth App 生成的 OAuth 访问令牌的速率限制由用户的 primary rate limit 决定。
- 对于 GitHub Actions 工作流程中的
GITHUB_TOKEN
:每个存储库每小时 1,000 积分。对于对属于 GitHub.com 上企业帐户的资源的请求,限制为每个存储库每小时 15,000 积分。
您可以检查查询的积分值或计算预期的积分值,如以下部分所述。计算积分和速率限制的公式可能会更改。
检查主要速率限制的状态
您可以使用每个响应发送的标头来确定主要速率限制的当前状态。
标头名称 | 说明 |
---|---|
x-ratelimit-limit | 您可以每小时使用的最大积分数 |
x-ratelimit-remaining | 当前速率限制窗口中剩余的积分数 |
x-ratelimit-used | 您在当前速率限制窗口中已使用的积分数 |
x-ratelimit-reset | 当前速率限制窗口重置的时间(UTC 纪元秒) |
x-ratelimit-resource | 请求针对的速率限制资源。对于 GraphQL 请求,这始终为graphql 。 |
您还可以查询rateLimit
对象以检查您的速率限制。在可能的情况下,您应该使用速率限制响应标头而不是查询 API 来检查您的速率限制。
query {
viewer {
login
}
rateLimit {
limit
remaining
used
resetAt
}
}
字段 | 说明 |
---|---|
limit | 您可以每小时使用的最大积分数 |
remaining | 当前速率限制窗口中剩余的积分数 |
used | 您在当前速率限制窗口中已使用的积分数 |
resetAt | 当前速率限制窗口重置的时间(UTC 纪元秒) |
返回查询的积分值
您可以通过查询rateLimit
对象上的cost
字段来返回查询的积分值
query {
viewer {
login
}
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**
次要速率限制
除了主要速率限制外,GitHub 还强制执行次要速率限制,以防止滥用并保持 API 对所有用户可用。
如果您执行以下操作,可能会遇到次要速率限制
- 发出过多并发请求。 不允许超过 100 个并发请求。此限制在 REST API 和 GraphQL API 中共享。
- 每分钟对单个端点发出过多请求。 REST API 端点每分钟最多允许 900 个积分,GraphQL API 端点每分钟最多允许 2,000 个积分。有关积分的更多信息,请参阅“计算次要速率限制的积分”。
- 每分钟发出过多请求。 每 60 秒的实际时间最多允许 90 秒的 CPU 时间。GraphQL API 的 CPU 时间最多不得超过 60 秒。您可以通过测量 API 请求的总响应时间来粗略估计 CPU 时间。
- 发出过多在短时间内消耗大量计算资源的请求。
- 在短时间内在 GitHub 上创建过多内容。 一般来说,每分钟最多允许 80 个内容生成请求,每小时最多允许 500 个内容生成请求。某些端点的创作内容限制较低。内容创建限制包括在 GitHub 网页界面以及通过 REST API 和 GraphQL API 执行的操作。
这些次要速率限制可能会随时更改,恕不另行通知。您也可能由于未公开的原因而遇到次要速率限制。
计算次要速率限制的积分
某些次要速率限制由请求的积分值决定。对于 GraphQL 请求,这些积分值与主要速率限制的积分值计算不同。
请求 | 积分 |
---|---|
没有更改的 GraphQL 请求 | 1 |
包含更改的 GraphQL 请求 | 5 |
大多数 REST API GET 、HEAD 和 OPTIONS 请求 | 1 |
大多数 REST API 的 POST 、PATCH 、PUT 或 DELETE 请求 | 5 |
某些 REST API 端点具有不同的点数成本,且不会公开共享。
超过速率限制
如果超过您的主要速率限制,响应状态仍将为 200
,但您会收到错误消息,并且 x-ratelimit-remaining
头部的值将为 0
。在 x-ratelimit-reset
头部指定的时间之后,您才应重试您的请求。
如果超过辅助速率限制,响应状态将为 200
或 403
,并且您将收到一条错误消息,指示您已达到辅助速率限制。如果存在 retry-after
响应头部,则在经过这么多秒后才应重试您的请求。如果 x-ratelimit-remaining
头部为 0
,则应在 x-ratelimit-reset
头部指定的 UTC 时间戳(秒)之后重试请求。否则,请至少等待一分钟后再重试。如果您的请求因辅助速率限制而继续失败,请在重试之间等待以指数方式增加的时间量,并在特定次数的重试后抛出错误。
在您受到速率限制时继续发出请求可能会导致您的集成被禁止。
保持在速率限制之下
为避免超过速率限制,您应在可变请求之间至少暂停 1 秒,并避免并发请求。
您还应该订阅 webhook 事件,而不是轮询 API 以获取数据。有关更多信息,请参阅“Webhook 文档”。