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 查询的不同方法。
身份验证
部分查询无需身份验证即可访问,但其他查询需要身份验证。变更操作始终需要身份验证。
您可以使用以下任一方式进行身份验证:
如果身份验证信息无效,极狐GitLab 会返回一条错误消息,状态码为 401:
json{"errors":[{"message":"Invalid token"}]}
令牌身份验证
使用以下任一令牌向 GraphQL API 进行身份验证:
令牌需要正确的范围。
请求头身份验证
使用 Authorization: Bearer <token> 请求头进行令牌身份验证的示例:
shellcurl --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 令牌的示例:
shellcurl --request POST \ --url "https://jihulab.com/api/graphql?access_token=<oauth_token>" \ --header "Content-Type: application/json" \ --data "{\"query\": \"query {currentUser {name}}\"}"
您可以使用 private_token 参数传入个人、项目或群组访问令牌:
shellcurl --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 的读写访问权限。变更操作需要此范围。 |
会话 Cookie 身份验证
登录极狐GitLab 主应用程序会设置一个 _gitlab_session 会话 Cookie。
交互式 GraphQL 浏览器和极狐GitLab 自身的 Web 前端使用此身份验证方法。
授权
身份验证后,GraphQL API 会检查您对每个所请求资源的权限。API 报告授权失败的方式取决于操作类型。
查询字段
当您没有访问某个资源的权限时,查询字段会返回 null。响应中不包含错误消息。
此行为是有意为之。对于未授权和不存在的资源,API 返回相同的 null 响应,这样客户端就无法枚举服务器上存在哪些资源。
例如,如果您查询的字段需要您不具备的角色或附加组件,则 errors 数组中不会显示任何条目:
json1{ 2 "data": { 3 "group": { 4 "fieldRequiringPermission": null 5 } 6 } 7}
对于使用 Relay 分页模式的连接字段,您可以区分授权失败和空结果:
- "field": null 表示您没有访问此资源的权限。
- "field": { "nodes": [] } 表示您有权限,但没有数据与您的查询匹配。
如果您收到意外的 null,请确认:
- 您的令牌具有所需的范围。
- 您的角色满足 GraphQL API 参考中记录的最低访问级别。
- 您的实例已启用所需的订阅层级、功能或附加组件。
变更操作
授权失败时,变更操作会返回错误消息。该错误会出现在顶层 errors 数组中,同时数据字段为 null:
json1{ 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 中都可用作参数,但通常 schema 的某个特定部分不会同时接受所有这些形式。
尽管极狐GitLab GraphQL API 在历史上对此并不一致,但一般来说您可以预期:
- 如果对象是项目、群组或命名空间,则使用对象的完整路径。
- 如果对象有 IID,则使用完整路径和 IID 的组合。
- 对于其他对象,则使用全局 ID。
例如,通过完整路径 "gitlab-cn/gitlab" 查找项目:
graphql1{ 2 project(fullPath: "gitlab-cn/gitlab") { 3 id 4 fullPath 5 } 6}
另一个示例,通过项目的完整路径 "gitlab-cn/gitlab" 和议题的 IID "1" 锁定议题:
graphql1mutation { 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。这些更改被视为破坏性变更,可能包括移除或重命名字段、参数或 schema 的其他部分。在创建破坏性变更时,极狐GitLab 遵循弃用和移除流程。
为避免破坏性变更影响您的集成,您应该:
破坏性变更豁免
在 GraphQL API 参考中标记为实验的 schema 项不受弃用流程约束。这些项可以随时移除或更改,恕不另行通知。
受功能标志控制且默认禁用的字段不遵循弃用和移除流程。这些字段可以随时移除,恕不另行通知。
极狐GitLab 尽一切努力遵循弃用和移除流程。 如果弃用流程会带来重大风险,极狐GitLab 可能会对 GraphQL API 立即进行破坏性变更,以修补关键的安全或性能问题。
针对未来的破坏性变更 schema 进行验证
您可以像所有已弃用项都已被移除一样对 GraphQL API 进行调用。这样,您就可以在破坏性变更发布之前、在项实际从 schema 中移除之前验证 API 调用。
要进行这些调用,请向 GraphQL API 端点添加 remove_deprecated=true 查询参数。例如,对于 JihuLab.com 上的 GraphQL,使用 https://jihulab.com/api/graphql?remove_deprecated=true。
弃用和移除流程
标记为要从极狐GitLab GraphQL API 中移除的 schema 部分会先被弃用,但至少仍可使用六个版本。然后在下一个 XX.0 主要版本中完全移除。
项在以下位置标记为已弃用:
- schema。
- GraphQL API 参考。
- 弃用功能移除计划,发布文章中会链接到该计划。
- GraphQL API 的内省查询。
弃用消息会为已弃用的 schema 项提供替代方案(如适用)。
为避免遭遇破坏性变更,您应尽快从 GraphQL API 调用中移除已弃用的 schema。您应针对不含已弃用 schema 项的 schema 验证您的 API 调用。
弃用示例
以下字段在不同的次要版本中被弃用,但都在极狐GitLab 17.0 中移除:
| 弃用版本 | 原因 |
|---|---|
| 15.7 | 极狐GitLab 传统上每个主要版本有 12 个次要版本。为确保该字段再可用 6 个版本,它在 17.0 主要版本(而非 16.0)中移除。 |
| 16.6 | 在 17.0 中移除可提供 6 个月的可用期。 |
已移除项列表
查看以往版本中的已移除项列表。
限制
以下限制适用于极狐GitLab GraphQL API。
最大页面大小
连接的默认最大页面大小为每页 100 条记录(节点)。连接 subscriptionUsage.usersUsage.users的最大页面大小为 20 条记录(节点)。
如果您请求的记录数超过连接的最大值,API 只会返回最大数量的记录。
最大查询复杂度
极狐GitLab GraphQL API 会对查询的复杂度进行评分。一般来说,查询越大,复杂度评分越高。此限制旨在保护 API,避免执行可能对其整体性能产生负面影响的查询。
您可以查询查询的复杂度评分以及请求的限制。
如果查询超过复杂度限制,将返回错误消息响应。
一般来说,查询中的每个字段都会使复杂度评分增加 1,但特定字段可能更高或更低。有时,添加某些参数也可能增加查询的复杂度。
数据限制
Blob 请求限制为:
- 任意大小的单个 blob。
- 总大小为 20 MB 或以下的多个 blob。
大于 20 MB 的 blob 必须单独请求。此限制仅适用于您请求包含 blob 数据的字段时。
您可能需要限制请求中的路径数量,以保持在数据限制之内。在排除数据字段的情况下请求 size 字段:
gql1{ 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 变更操作可能被检测为垃圾信息。如果某个变更操作被检测为垃圾信息,并且:
-
未配置 CAPTCHA 服务,则会引发 GraphQL 顶层错误。例如:
json1{ 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 字段已设置。
例如:
json1{ 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 内嵌查询中 转义的双引号。
shell1export 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"