GraphQL API

  1. Tier: 基础版, 专业版, 旗舰版
  2. 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,可以:

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

有关更多信息,请参阅 GraphiQL

查看 GraphQL 示例#

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

  1. 创建审计报告
  2. 识别议题板
  3. 查询用户
  4. 使用自定义表情符号

入门页面包括定制 GraphQL 查询的不同方法。

认证#

您可以在不进行认证的情况下访问某些查询,但其他查询需要认证。变更总是需要认证。

您可以通过以下方式之一进行认证:

  1. 令牌
  2. 会话 cookie

如果认证信息无效,极狐GitLab 将返回状态码为 401 的错误消息:

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

令牌认证#

使用以下任一令牌进行 GraphQL API 的认证:

  1. OAuth 2.0 令牌
  2. 个人访问令牌
  3. 项目访问令牌
  4. 群组访问令牌

通过在请求头或作为参数传递令牌来进行认证。

令牌需要正确的范围

请求头认证#

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

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

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

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

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

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

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

ScopeAccess
read_api授予 API 的读取访问权限。足够用于查询。
api授予 API 的读写访问权限。变更需要。

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

交互式 GraphQL 浏览器和极狐GitLab 自身的网页前端使用这种认证方法。

对象标识符#

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

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

虽然极狐GitLab GraphQL API 在此方面历史上不一致,但一般情况下您可以预期:

  1. 如果对象是项目、群组或命名空间,您使用对象的完整路径。
  2. 如果对象有 IID,您使用完整路径和 IID 的组合。
  3. 对于其他对象,您使用全局 ID

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

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

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

graphql
1mutation { 2 issueSetLocked(input: { projectPath: "gitlab-org/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 字段及参数的类型上不一致,但通常:

  1. 完整路径字段和参数是 GraphQL ID 类型。
  2. 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 遵循弃用和移除流程

为了避免重大更改影响您的集成,您应该:

  1. 熟悉弃用和移除流程
  2. 经常验证您的 API 调用是否符合未来的重大更改模式

有关更多信息,请参阅弃用极狐GitLab 功能

对于极狐GitLab 私有化部署,从 EE 实例降级到 CE 会导致重大更改。

重大更改豁免#

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

默认情况下禁用且启用了功能标志的字段不遵循弃用和移除过程。这些字段可以随时删除,恕不另行通知。

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

验证未来重大更改模式#

History
    • 在极狐GitLab 15.6 中引入。

您可以进行 API 调用,就好像所有弃用的项目已经被移除一样。通过这种方式,您可以在实际从模式中移除项目之前,提前验证 API 调用是否符合重大更改版本

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

弃用和移除流程#

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

项目被标记为弃用的地方有:

  1. 模式。
  2. GraphQL API 参考
  3. 弃用功能移除计划,该计划链接自发布帖子。
  4. GraphQL API 的自省查询。

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

为了避免遇到重大更改,您应尽快从您的 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 特定速率限制
请求超时30 秒。

最大查询复杂度#

极狐GitLab GraphQL API 评估查询的_复杂度_。通常,较大的查询具有更高的复杂度得分。此限制旨在保护 API,防止执行可能会对其整体性能产生负面影响的查询。

您可以查询查询的复杂度得分和请求的限制。

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

一般来说,查询中的每个字段都为复杂度得分增加 1,尽管对于特定字段这可能更高或更低。有时,添加某些参数也可能增加查询的复杂度。

解决检测为垃圾邮件的变更#

GraphQL 变更可能被检测为垃圾邮件。如果检测到变更为垃圾邮件并且:

  1. 未配置 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}
  1. 配置了 CAPTCHA 服务,您会收到一个响应,其中:
  • needsCaptchaResponse 设置为 true
  • 设置了 spamLogIdcaptchaSiteKey 字段。

例如:

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}
  1. 使用 captchaSiteKey 使用适当的 CAPTCHA API 获取 CAPTCHA 响应值。
  2. 使用设置的 X-GitLab-Captcha-ResponseX-GitLab-Spam-Log-Id 头重新提交请求。

极狐GitLab GraphiQL 实现不允许传递头,因此我们必须将其编写为 cURL 查询。使用 --data-binary 以正确处理 JSON 嵌入查询中的转义双引号。

shell
export CAPTCHA_RESPONSE="<CAPTCHA response obtained from CAPTCHA service>" export SPAM_LOG_ID="<spam_log_id obtained from initial REST response>" curl --header "Authorization: Bearer $PRIVATE_TOKEN" --header "Content-Type: application/json" --header "X-GitLab-Captcha-Response: $CAPTCHA_RESPONSE" --header "X-GitLab-Spam-Log-Id: $SPAM_LOG_ID" --request POST --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"