极狐 GitLab

GraphQL API

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

Offering: JihuLab.com,私有化部署

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

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

极狐GitLab 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 查询的不同方法。

身份验证#

访问某些查询无需身份验证,但另一些则需要。变更总是需要身份验证。

你可以使用以下任一方式进行身份验证:

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

json
{"errors":[{"message":"无效的令牌"}]}

令牌身份验证#

使用以下任一令牌对 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 的读写权限。变更操作所必需。

登录到极狐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 参考文档中记录的最低访问级别。
  • 你的实例启用了所需的订阅级别、功能或附加组件。

变更#

当授权失败时,变更会返回一条错误消息。错误出现在顶层 errors 数组中,同时 data 字段为 null

json
1{ 2 "data": { 3 "mutationName": null 4 }, 5 "errors": [ 6 { 7 "message": "你尝试访问的资源不存在或你没有权限执行此操作", 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 支持将查询批处理到单个请求中。有关更多信息,请参阅多路复用

破坏性变更#

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

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

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

对于极狐GitLab 私有化部署,从 EE 实例回退到 CE 会导致破坏性变更。

破坏性变更豁免#

GraphQL API 参考文档中标记为实验的架构条目不受弃用流程的约束。这些条目可以随时被移除或更改,恕不另行通知。

位于功能标志之后且默认禁用的字段不遵循弃用和移除流程。这些字段可以随时被移除,恕不另行通知。

极狐GitLab 会尽一切努力遵循[弃用和移除流程](#deprecation-and-removal-process)。 如果弃用流程会带来重大风险,极狐GitLab 可能会立即对 GraphQL API 进行破坏性变更,以修补严重的安全或性能问题。

针对未来的破坏性变更架构进行验证#

版本历史
  • 在极狐GitLab 15.6 引入,带有一个名为 maven_central_request_forwarding 的功能标志,默认禁用。
  • 所需角色从维护者更改为所有者在极狐GitLab 17.0。

你可以像已删除所有已弃用条目一样对 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。
最大查询大小每个查询或变更 10,000 个字符。如果达到此限制,请使用变量片段来减小查询或变更的大小。最后的手段是移除空白字符。
速率限制对于 JihuLab.com,请参阅 JihuLab.com 特定的速率限制
数据限制当指定多个 blob 路径时,blob 请求限制为 20 MB。
请求超时30 秒。

最大查询复杂度#

极狐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 的数据限制。

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

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

  • 未配置验证码服务,则会引发 GraphQL 顶层错误。例如:

    json
    1{ 2 "errors": [ 3 { 4 "message": "请求被拒绝。检测到垃圾信息", 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}
  • 配置了验证码服务,你会收到一个响应,其中包含:

    • needsCaptchaResponse 设置为 true
    • spamLogIdcaptchaSiteKey 字段已设置。

    例如:

    json
    1{ 2 "errors": [ 3 { 4 "message": "请求被拒绝。请解决验证码挑战并重试", 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,通过适当的验证码 API 获取验证码响应值。 仅支持 Google reCAPTCHA v2

  • 重新提交带有 X-GitLab-Captcha-ResponseX-GitLab-Spam-Log-Id 标头的请求。

极狐GitLab GraphiQL 实现不允许传递标头,因此请求必须是 cURL 查询。使用 `--data-binary` 来正确处理 JSON 嵌入查询中 的转义双引号。
shell
1export CAPTCHA_RESPONSE="<验证码服务获取的验证码响应>" 2export SPAM_LOG_ID="<从初始 REST 响应中获取的 spam_log_id>" 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"