GraphQL API

启用并广泛可用于极狐GitLab 12.1。功能标志 graphql 已移除。

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

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

使用 GraphQL

如果您不熟悉极狐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

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

令牌认证

  • 认证方法限制自极狐GitLab 17.0 引入,使用名为 graphql_minimal_auth_methods 的功能标志,并后向兼容 17.0.3 和 16.11.5。在 17.0 中默认禁用。
  • 在极狐GitLab 17.0.3 和 16.11.5 中,功能开关默认启用,因此在 17.0.3 和 16.11.5 及更高版本中,会强制执行这些限制。

使用以下任意一种令牌来对 GraphQL API 进行认证:

通过在请求标头参数中传递令牌来进行认证。

令牌需要有正确的范围

标头认证

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

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 令牌的示例如下:

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

您可以在 private_token 参数中使用个人、项目或群组访问令牌来进行认证:

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

令牌范围

令牌需要有正确的范围来访问 GraphQL API:

范围 访问权限
read_api 给 API 赋予读权限。对于查询来说是必须的。
api 给 API 赋予读写权限。在变更查询时是必须的。

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

交互式 GraphQL 浏览器和极狐GitLab 自身的 web 前端使用此方法进行认证。

对象标识符

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

全局 ID、完整路径、内部标识符(IID)都是 GraphQL API 中使用的标识符,但是通常情况下,特定部分架构不会同时接受所有这些标识符。

尽管极狐GitLab GraphQL API 历史上在这方面不一致,但通常情况下,您应该使用以下规则来确定要使用哪种标识符:

  • 如果对象是一个项目、群组或命名空间,您可以使用对象的完整路径。
  • 如果对象有一个 IID,您可以结合使用 IID 和完整路径。
  • 对于其他对象,您使用全局 ID

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

{
  project(fullPath: "gitlab-org/gitlab") {
    id
    fullPath
  }
}

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

mutation {
  issueSetLocked(input: { projectPath: "gitlab-org/gitlab", iid: "1", locked: true }) {
    issue {
      id
      iid
    }
  }
}

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

{
  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 API 的顶层查询是定义在 Query 类型中的。

多路复用查询

极狐GitLab 支持在单个请求中进行批量查询。更多详情,可以查看多路复用

重大更改

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

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

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

更多内容,请参见废弃极狐GitLab 功能

重大变更豁免

极狐GitLab API 引用中被标记为实验性的模式条目(schema items)不受此流程影响。这些模式条目可能随时被移除或更改,而不会发出警告。

功能开关背后的字段以及默认禁用的功能不会遵循弃用和移除流程。这些字段可能随时被移除或更改,而不会发出警告。

caution 极狐GitLab 会努力尝试以遵循弃用和移除流程。如果极狐GitLab 需要立即修补安全或性能问题,极狐GitLab 可能会以不遵循弃用和移除流程的方式对 GraphQL API 进行重大安全更改。

针对未来重大更改架构进行验证

引入于极狐GitLab 15.6。

您可以对 GraphQL API 进行调用,就好像所有已弃用的项目都已经被移除一样。 这样,您可以在项目实际从架构中删除之前,在重大更改发布之前验证 API 调用。

要进行这些调用,请向极狐GitLab GraphQL API 端点(例如,适用于极狐GitLab SaaS GraphQL 的 https://gitlab.com/api/graphql?remove_deprecated=true ) 添加一个 remove_deprecated=true 查询参数。

废弃和移除流程

极狐GitLab GraphQL API 的废弃和移除流程与更广泛的极狐GitLab 废弃流程保持一致。

标记为从极狐GitLab GraphQL API 中移除的部分结构已废弃, 但仍可用于至少六个版本。然后将其完全移除于下一个 XX.0 的主要版本中。

条目会在如下内容中被标记为弃用:

如果适用,弃用消息会提供被弃用模式项的替代方案。

note 如果您使用 GraphQL API,我们建议您从 GraphQL API 调用中尽快移除已废弃的架构,以避免遇到重大更改。

您应该在没有弃用的架构项的情况下,针对架构验证您的 API 调用

废弃示例

以下字段在不同的小版本发布中都已废弃,但都移除于 14.0。

字段废弃版本 原因
15.7 极狐GitLab 每次大版本发布都有 12 个小版本发布,为确保字段在超过 6 次发布中可用,其移除于 17.0 大版本发布(不是 16.0)
16.6 17.0 中的移除允许 6 个月的可用性

移除条目列表

请查看先前发布中的移除条目列表

限制

极狐GitLab GraphQL API 有以下限制:

限制 默认  
  最大页面大小 每页 100 个记录(节点)。适用于 API 中的多数连接。特定连接的最大页面大小限制可能不同,或大或小
  最大查询复杂度 未授权请求:200;授权请求:250
  最大查询大小 每个查询 10,000 个字符。如果达到此限制,请使用变量Fragment 来减少查询大小。可以删除空格作为减少大小的方法。
  请求超时时间 30 秒
  Rate limits 对 JihuLab.com,可查看 JihuLab.com 特定的速率限制.

最大查询复杂度

极狐GitLab GraphQL API 对查询的复杂度进行评分。一般来说,较大的查询具有更高的复杂度分数。 此限制旨在保护 API 执行可能对其整体性能产生负面影响的查询。

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

如果查询超出复杂性限制,则会返回错误消息响应。

通常情况下,查询中的每个字段都会在复杂度得分上加 1,尽管对于特定领域会更高或更低。有时,添加某些参数也可能增加查询的复杂性。

note 未来可能会修改复杂性限制。此外,查询的复杂性也可能会更改。

解决检测为垃圾邮件的 Mutation

GraphQL Mutation 可能会被检测为垃圾邮件。如果其被检测为垃圾邮件并且:

  • 未配置 CAPTCHA 服务,会出现 GraphQL 顶级错误。例如:

    {
      "errors": [
        {
          "message": "Request denied. Spam detected",
          "locations": [ { "line": 6, "column": 7 } ],
          "path": [ "updateSnippet" ],
          "extensions": {
            "spam": true
          }
        }
      ],
      "data": {
        "updateSnippet": {
          "snippet": null
        }
      }
    }
    
  • 配置了 CAPTCHA 服务,您会收到带有以下内容的响应:
    • needsCaptchaResponse 设置为 true
    • 设置了 spamLogIdcaptchaSiteKey 字段

    例如:

    {
      "errors": [
        {
          "message": "Request denied. Solve CAPTCHA challenge and retry",
          "locations": [ { "line": 6, "column": 7 } ],
          "path": [ "updateSnippet" ],
          "extensions": {
            "needsCaptchaResponse": true,
            "captchaSiteKey": "6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI",
            "spamLogId": 67
          }
        }
      ],
      "data": {
        "updateSnippet": {
          "snippet": null,
        }
      }
    }
    
  • 使用合适的 CAPTCHA API 通过 captchaSiteKey 获取 CAPTCHA 响应值。 仅支持 Google reCAPTCHA v2
  • 设置 X-GitLab-Captcha-ResponseX-GitLab-Spam-Log-Id Header,重新提交请求。
note 极狐GitLab GraphiQL 实现不允许传递 Header,因此我们必须将其写为 cURL 查询。--data-binary 用于在 JSON 嵌入式查询中正确处理转义的双引号。
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"