极狐 GitLab

GraphQL API

Tier: 基础版,专业版,旗舰版

Offering: JihuLab.com,私有化部署

GraphQL 是一种用于 API 的查询语言。您可以使用它来请求所需的确切数据,从而限制所需的请求数量。

GraphQL 数据按类型组织,因此您的客户端可以使用客户端 GraphQL 库来使用 API,并避免手动解析。

GraphQL API 是无版本的。

入门#

如果您是极狐GitLab GraphQL API 的新手,请参阅极狐GitLab GraphQL API 入门。

您可以在 GraphQL API 参考中查看可用资源。

极狐GitLab GraphQL API 端点位于 /api/graphql。

交互式 GraphQL 浏览器#

使用交互式 GraphQL 浏览器探索 GraphQL API,可以:

  • 在 JihuLab.com 上。
  • 在极狐GitLab 私有化部署上,地址为 https://<your-gitlab-site.com>/-/graphql-explorer。

有关更多信息,请参阅 GraphiQL。

查看 GraphQL 示例#

您可以使用从 JihuLab.com 上的公共项目拉取数据的示例查询:

入门页面包含自定义 GraphQL 查询的不同方法。

身份验证#

您可以在不进行身份验证的情况下访问某些查询,但其他查询需要身份验证。变更(Mutation)始终需要身份验证。

您可以通过以下任一方式进行身份验证:

如果身份验证信息无效,极狐GitLab 会返回状态码为 401 的错误消息:

json
{"errors":[{"message":"Invalid token"}]}

令牌身份验证#

使用以下任一令牌通过 GraphQL API 进行身份验证:

通过请求头或参数传递令牌进行身份验证。

令牌需要正确的范围。

请求头身份验证#

使用 Authorization: Bearer <token> 请求头进行令牌身份验证的示例:

shell
curl --request POST \ --url "https://jihulab.com/api/graphql" \ --header "Authorization: Bearer <token>" \ --header "Content-Type: application/json" \ --data "{\"query\": \"query {currentUser {name}}\"}"
参数身份验证#

在 access_token 参数中使用 OAuth 2.0 令牌的示例:

shell
curl --request POST \ --url "https://jihulab.com/api/graphql?access_token=<oauth_token>" \ --header "Content-Type: application/json" \ --data "{\"query\": \"query {currentUser {name}}\"}"

您可以使用 private_token 参数传递个人、项目或群组访问令牌:

shell
curl --request POST \ --url "https://jihulab.com/api/graphql?private_token=<access_token>" \ --header "Content-Type: application/json" \ --data "{\"query\": \"query {currentUser {name}}\"}"
令牌范围#

令牌必须具有正确的范围才能访问 GraphQL API,可以是:

范围访问权限
read_api授予 API 的读取访问权限。足以用于查询。
api授予 API 的读取和写入访问权限。变更(Mutation)需要此权限。

登录主极狐GitLab 应用程序会设置一个 _gitlab_session 会话 Cookie。

交互式 GraphQL 浏览器和极狐GitLab 本身的 Web 前端使用此身份验证方法。

授权#

身份验证后,GraphQL API 会检查您对每个请求资源的权限。API 报告授权失败的方式取决于操作类型。

查询字段#

当您没有权限访问资源时,查询字段返回 null。响应不包含错误消息。

此行为是有意为之。API 对未授权和不存在的资源返回相同的 null 响应,以便客户端无法枚举服务器上存在哪些资源。

例如,如果您查询需要您不具备的角色或附加组件的字段,则 errors 数组中不会显示任何条目:

json
1{ 2 "data": { 3 "group": { 4 "fieldRequiringPermission": null 5 } 6 } 7}

对于使用 Relay 分页模式的连接字段,您可以区分授权失败和空结果:

  • "field": null 表示您没有权限访问此资源。
  • "field": { "nodes": [] } 表示您有权限,但没有数据与您的查询匹配。

如果您收到意外的 null,请验证:

  • 您的令牌具有所需的范围。
  • 您的角色满足 GraphQL API 参考中记录的最低访问级别。
  • 您的实例已启用所需的订阅层级、功能或附加组件。

变更(Mutation)#

当授权失败时,变更(Mutation)会返回错误消息。该错误出现在顶层 errors 数组中,同时数据字段为 null:

json
1{ 2 "data": { 3 "mutationName": null 4 }, 5 "errors": [ 6 { 7 "message": "The resource that you are attempting to access does not exist or you don't have permission to perform this action", 8 "locations": [{ "line": 2, "column": 3 }], 9 "path": ["mutationName"] 10 } 11 ] 12}

错误消息可能因资源类型而异。

对象标识符#

极狐GitLab GraphQL API 使用混合的标识符。

全局 ID、完整路径和内部 ID(IID)都用作极狐GitLab GraphQL API 中的参数,但通常模式的特定部分不会同时接受所有这些参数。

尽管极狐GitLab GraphQL API 历来在这方面并不一致,但通常您可以预期:

  • 如果对象是项目、群组或命名空间,则使用该对象的完整路径。
  • 如果对象具有 IID,则使用完整路径和 IID 的组合。
  • 对于其他对象,则使用全局 ID。

例如,通过完整路径 "gitlab-cn/gitlab" 查找项目:

graphql
1{ 2 project(fullPath: "gitlab-cn/gitlab") { 3 id 4 fullPath 5 } 6}

另一个示例,通过项目的完整路径 "gitlab-cn/gitlab" 和议题的 IID "1" 锁定议题:

graphql
1mutation { 2 issueSetLocked(input: { projectPath: "gitlab-cn/gitlab", iid: "1", locked: true }) { 3 issue { 4 id 5 iid 6 } 7 } 8}

通过其全局 ID 查找 CI Runner 的示例:

graphql
{ runner(id: "gid://gitlab/Ci::Runner/1") { id } }

历史上,极狐GitLab GraphQL API 在完整路径和 IID 字段及参数的类型方面一直不一致,但通常:

  • 完整路径字段和参数是 GraphQL ID 类型。
  • IID 字段和参数是 GraphQL String 类型。

全局 ID#

在极狐GitLab GraphQL API 中,名为 id 的字段或参数几乎总是全局 ID,而绝不是数据库主键 ID。极狐GitLab GraphQL API 中的全局 ID 以 "gid://gitlab/" 开头。例如,"gid://gitlab/Issue/123"。

全局 ID 是某些客户端库中用于缓存和获取的约定。

极狐GitLab 全局 ID 可能会发生变化。如果发生变化,将旧全局 ID 用作参数的做法将被弃用,并根据弃用和破坏性变更流程提供支持。您不应期望缓存的全局 ID 在极狐GitLab GraphQL 弃用周期之后仍然有效。

可用的顶级查询#

所有查询的顶级入口点定义在 GraphQL 参考中的 Query 类型中。

多路复用查询#

极狐GitLab 支持将多个查询批处理到单个请求中。有关更多信息,请参阅 Multiplex。

破坏性变更#

极狐GitLab GraphQL API 是无版本的,对 API 的更改主要是向后兼容的。

然而,极狐GitLab 有时会以不向后兼容的方式更改 GraphQL API。这些更改被视为破坏性变更,可能包括删除或重命名字段、参数或模式的其他部分。在创建破坏性变更时,极狐GitLab 遵循弃用和移除流程。

为避免破坏性变更影响您的集成,您应该:

对于极狐GitLab 私有化部署,从企业版实例回退到基础版会导致破坏性变更。

破坏性变更豁免#

GraphQL API 参考中标记为实验的模式项不受弃用流程的约束。这些项可以随时删除或更改,恕不另行通知。

受功能标志控制且默认禁用的字段不遵循弃用和移除流程。这些字段可以随时删除,恕不另行通知。

极狐GitLab 尽一切努力遵循弃用和移除流程。 如果弃用流程可能带来重大风险,极狐GitLab 可能会对 GraphQL API 进行即时破坏性更改,以修补关键的安全或性能问题。

根据未来的破坏性变更模式进行验证#

您可以像所有弃用项都已被移除一样调用 GraphQL API。这样,您可以在破坏性变更版本发布之前,在实际从模式中移除这些项之前,验证 API 调用。

要进行这些调用,请在 GraphQL API 端点添加 remove_deprecated=true 查询参数。例如,JihuLab.com 上的 GraphQL 使用 https://jihulab.com/api/graphql?remove_deprecated=true。

弃用和移除流程#

标记为从极狐GitLab GraphQL API 中移除的模式部分首先被弃用,但仍至少可用六个版本。然后,它们会在下一个 XX.0 主版本中完全移除。

项目在以下位置被标记为弃用:

弃用消息为弃用的模式项提供了替代方案(如果适用)。

为避免遇到破坏性变更,您应尽快从 GraphQL API 调用中移除已弃用的模式。您应该根据不包含已弃用模式项的模式验证您的 API 调用。

弃用示例#

以下字段在不同的次要版本中被弃用,但都在极狐GitLab 17.0 中移除:

弃用字段的版本原因
15.7极狐GitLab 传统上每个主版本有 12 个次要版本。为确保该字段再可用 6 个版本,它在 17.0 主版本(而非 16.0)中被移除。
16.6在 17.0 中移除可确保 6 个月的可用期。

已移除项目列表#

查看先前版本中已移除项目列表。

限制#

以下限制适用于极狐GitLab GraphQL API。

限制默认值
最大页面大小每页 100 条记录(节点)。适用于 API 中的大多数连接。某些连接的最大页面大小可能不同于默认值。
最大查询复杂度未认证请求为 200,已认证请求为 250。
最大查询大小每个查询或变更(Mutation)为 10,000 个字符。如果达到此限制,请使用变量和片段来减小查询或变更(Mutation)的大小。最后的手段是删除空白字符。
速率限制对于 JihuLab.com,请参阅 JihuLab.com 特定速率限制。
数据限制当指定多个 blob 路径时,blob 请求限制为 20 MB。
请求超时30 秒。

最大页面大小#

连接的默认最大页面大小为每页 100 条记录(节点)。连接 subscriptionUsage.usersUsage.users 的最大页面大小为 20 条记录(节点)。

如果您请求的记录数超过连接的最大值,API 仅返回最大数量的记录。

最大查询复杂度#

极狐GitLab GraphQL API 会为查询的复杂度评分。通常,较大的查询具有较高的复杂度分数。此限制旨在保护 API 免受可能对其整体性能产生负面影响的查询的影响。

您可以查询查询的复杂度分数以及请求的限制。

如果查询超过复杂度限制,将返回错误消息响应。

通常,查询中的每个字段都会为复杂度分数增加 1,尽管特定字段可能更高或更低。有时,添加某些参数也可能增加查询的复杂度。

数据限制#

Blob 请求限制为:

  • 任意大小的单个 blob。
  • 总大小为 20 MB 或更小的多个 blob。

大于 20 MB 的 blob 必须单独请求。此限制仅在您请求包含 blob 数据的字段时适用。

您可能需要限制请求中的路径数量,以保持在数据限制内。在排除数据字段的情况下请求 size 字段:

gql
1{ 2 project(fullPath: "gitlab-cn/gitlab") { 3 repository { 4 blobs(paths: ["big_file.rb", "small_file.rb", "huge_file.rb", ..., etc.], ref: "master") { 5 nodes { 6 path 7 size 8 } 9 } 10 } 11 } 12}

使用响应计算总大小,并确保后续请求不超过 20 MB 的数据限制。

解决被检测为垃圾信息的变更(Mutation)#

GraphQL 变更(Mutation)可能被检测为垃圾信息。如果变更(Mutation)被检测为垃圾信息,并且:

  • 未配置 CAPTCHA 服务,则会引发 GraphQL 顶级错误。例如:

    json
    1{ 2 "errors": [ 3 { 4 "message": "Request denied. Spam detected", 5 "locations": [ { "line": 6, "column": 7 } ], 6 "path": [ "updateSnippet" ], 7 "extensions": { 8 "spam": true 9 } 10 } 11 ], 12 "data": { 13 "updateSnippet": { 14 "snippet": null 15 } 16 } 17}
  • 已配置 CAPTCHA 服务,您会收到包含以下内容的响应:

    • needsCaptchaResponse 设置为 true。
    • 设置了 spamLogId 和 captchaSiteKey 字段。

    例如:

    json
    1{ 2 "errors": [ 3 { 4 "message": "Request denied. Solve CAPTCHA challenge and retry", 5 "locations": [ { "line": 6, "column": 7 } ], 6 "path": [ "updateSnippet" ], 7 "extensions": { 8 "needsCaptchaResponse": true, 9 "captchaSiteKey": "6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI", 10 "spamLogId": 67 11 } 12 } 13 ], 14 "data": { 15 "updateSnippet": { 16 "snippet": null, 17 } 18 } 19}
  • 使用 captchaSiteKey 通过相应的 CAPTCHA API 获取 CAPTCHA 响应值。 仅支持 Google reCAPTCHA v2。

  • 使用设置了 X-GitLab-Captcha-Response 和 X-GitLab-Spam-Log-Id 请求头的请求重新提交。

极狐GitLab GraphiQL 实现不允许传递请求头,因此请求必须是 cURL 查询。使用 --data-binary 来正确处理 JSON 嵌入查询中的转义双引号。

shell
1export CAPTCHA_RESPONSE="<CAPTCHA response obtained from CAPTCHA service>" 2export SPAM_LOG_ID="<spam_log_id obtained from initial REST response>" 3curl --request POST \ 4 --header "Authorization: Bearer $PRIVATE_TOKEN" \ 5 --header "Content-Type: application/json" \ 6 --header "X-GitLab-Captcha-Response: $CAPTCHA_RESPONSE" \ 7 --header "X-GitLab-Spam-Log-Id: $SPAM_LOG_ID" \ 8 --data-binary '{"query": "mutation {createSnippet(input: {title: \"Title\" visibilityLevel: public blobActions: [ { action: create filePath: \"BlobPath\" content: \"BlobContent\" } ] }) { snippet { id title } errors }}"}' "https://gitlab.example.com/api/graphql"