API 文档

使用 GitLab API 自动化极狐GitLab。

REST API

极狐GitLab 中提供了 REST API。 使用说明如下。

有关示例,请参阅如何使用 API

GraphQL API

极狐GitLab 中提供了 GraphQL API。

使用 GraphQL,您可以只针对您需要的内容发出 API 请求,并且默认情况下它是版本化的。

GraphQL 与当前的 v4 REST API 共存。如果有 v5 API,应该是 GraphQL 之上的兼容层。

兼容性指南

HTTP API 使用单个数字进行版本控制,目前为 4。此数字表示主要版本号,如 SemVer 所述。 因此,向后不兼容的更改需要更改此版本号。

次要版本不是显式的,它允许稳定的 API 端点。可以在相同版本号的 API 中添加新功能。

当前状态

只有 API 版本 v4 可用。

如何使用 API

API 请求必须同时包含 api 和 API 版本。API 版本在 lib/api.rb 中定义。 例如,v4 API 的根目录位于 /api/v4

有效的 API 请求

以下是对虚构的 gitlab.example.com 端点的请求的基本示例:

curl "https://gitlab.example.com/api/v4/projects"

API 使用 JSON 来序列化数据。您无需在 API URL 的末尾指定 .json

公开 HTTP 响应头的 API 请求

如果要公开 HTTP 响应头,请使用 --include 选项:

curl --include "https://gitlab.example.com/api/v4/projects"
HTTP/2 200
...

此请求可以帮助您调查意外响应。

包含退出码的 API 请求

如果要公开 HTTP 退出码,请包含 --fail 选项:

curl --fail "https://gitlab.example.com/api/v4/does-not-exist"
curl: (22) The requested URL returned error: 404

HTTP 退出码可以帮助您诊断 REST 请求的成功或失败。

验证

大多数 API 请求都需要身份验证,或者仅在未提供身份验证时才返回公共数据。当不需要身份验证时,每个端点的文档都会说明这一点。例如,/projects/:id 端点不需要身份验证。

您可以通过多种方式使用 GitLab API 进行身份验证:

项目访问令牌受以下支持:

  • 私有化部署版的免费版及更高版本。
  • SaaS 版的专业版及更高版本。

如果您是管理员,您或您的应用程序可以作为特定用户进行身份验证。 请使用:

如果身份验证信息无效或丢失,系统会返回一条错误消息,状态码为 401:

{
  "message": "401 Unauthorized"
}
note部署令牌不能与 GitLab 公共 API 一起使用。有关详细信息,请参阅部署令牌

OAuth2 令牌

您可以使用 OAuth2 令牌,通过在 access_token 参数或 Authorization header 中传递 API 来进行身份验证。

在参数中使用 OAuth2 令牌的示例:

curl "https://gitlab.example.com/api/v4/projects?access_token=OAUTH-TOKEN"

在 header 中使用 OAuth2 令牌的示例:

curl --header "Authorization: Bearer OAUTH-TOKEN" "https://gitlab.example.com/api/v4/projects"
note我们建议 OAuth 访问令牌有期限。您可以使用 refresh_token 参数来刷新令牌。可能需要更新集成,从而在到期前使用刷新令牌,这基于令牌端点响应中的 expires_in 属性。

个人/项目/群组访问令牌

您可以通过将访问令牌传递给 private_token 参数或 PRIVATE-TOKEN header,来使用访问令牌对 API 进行身份验证。

在参数中使用个人、项目或群组访问令牌的示例:

curl "https://gitlab.example.com/api/v4/projects?private_token=<your_access_token>"

在 header 中使用个人、项目或群组访问令牌的示例:

curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects"

您还可以将个人、项目或群组访问令牌与符合 OAuth 的 header 一起使用:

curl --header "Authorization: Bearer <your_access_token>" "https://gitlab.example.com/api/v4/projects"

登录到极狐GitLab 主应用程序会设置一个 _gitlab_session cookie。API 使用此 cookie 进行身份验证(如果存在)。不支持使用 API 生成新的会话 cookie。

这种身份验证方法的主要用户是极狐GitLab 本身的 Web 前端。Web 前端可以使用 API 作为经过身份验证的用户来获取项目列表,而无需显式传递访问令牌。

模拟令牌

模拟令牌是个人访问令牌的一种。 它们只能由管理员创建,并用于特定用户使用 API 时进行身份验证。

使用模拟令牌替代:

  • 用户的密码或他们的个人访问令牌之一。
  • Sudo 功能。用户或管理员的密码或令牌可能不为人所知,或者可能会随着时间而改变。

模拟令牌的使用与常规个人访问令牌完全相同,可以在 private_token 参数或 PRIVATE-TOKEN header 中传递。

禁用模拟

默认情况下,模拟已启用。要禁用模拟:

Omnibus 安装实例

  1. 编辑 /etc/gitlab/gitlab.rb 文件:

    gitlab_rails['impersonation_enabled'] = false
    
  2. 保存文件,然后重新配置极狐GitLab,使更改生效。

要重新启用模拟,请删除此配置,然后重新配置极狐GitLab。

源安装实例

  1. 编辑 config/gitlab.yml 文件:

    gitlab:
      impersonation_enabled: false
    
  2. 保存文件,然后重启极狐GitLab,使更改生效。

要重新启用模拟,请删除此配置,然后重新启动极狐GitLab。

Sudo

您使用具有 sudo 范围的 OAuth 或个人访问令牌作为管理员进行身份验证时,所有 API 请求都支持您像是其它用户一样执行 API 请求。API 请求以模拟用户的权限执行。

作为管理员,通过使用查询字符串,或带有您要执行操作的用户的 ID,或用户名(不区分大小写)的 header 传递 sudo 参数。如果作为 header 传递,header 名称必须是 Sudo

如果提供了非管理访问令牌,系统将返回状态代码为 403 的错误消息:

{
  "message": "403 Forbidden - Must be admin to use sudo"
}

如果提供了没有 sudo 范围的访问令牌,则会返回错误消息,状态码为 403

{
  "error": "insufficient_scope",
  "error_description": "The request requires higher privileges than provided by the access token.",
  "scope": "sudo"
}

如果找不到 sudo 用户 ID 或用户名,则返回错误消息,状态码为 404

{
  "message": "404 User with ID or username '123' Not Found"
}

有效 API 请求,和使用 cURL 以及 sudo 的请求的示例,提供用户名:

GET /projects?private_token=<your_access_token>&sudo=username
curl --header "PRIVATE-TOKEN: <your_access_token>" --header "Sudo: username" "https://gitlab.example.com/api/v4/projects"

有效 API 请求,和使用 cURL 以及 sudo 的请求的示例,提供 ID:

GET /projects?private_token=<your_access_token>&sudo=23
curl --header "PRIVATE-TOKEN: <your_access_token>" --header "Sudo: 23" "https://gitlab.example.com/api/v4/projects"

状态码

API 旨在根据上下文和操作返回不同的状态码。如果请求导致错误,您可以深入了解问题所在。

下表概述了 API 函数的一般行为方式。

请求类型 描述
GET 访问一个或多个资源并将结果作为 JSON 返回。
POST 如果资源创建成功,则返回 201 Created,并以 JSON 格式返回新创建的资源。
GET / PUT 如果资源访问或修改成功,则返回 200 OK。(修改后的)结果以 JSON 形式返回。
DELETE 如果资源被成功删除,则返回 204 No Content。如果计划删除资源,则返回 202 Accepted

下表显示了 API 请求的可能返回码。

返回值 描述
200 OK GETPUTDELETE 请求成功,资源本身以 JSON 形式返回。
202 Accepted GETPUTDELETE 请求成功,资源被安排处理。
204 No Content 服务器已成功完成请求,并且响应负载正文中没有要发送的其他内容。
201 Created POST 请求成功,资源以 JSON 形式返回。
304 Not Modified 自上次请求以来,该资源尚未修改。
400 Bad Request 缺少 API 请求的必需属性。例如,没有给出议题的标题。
401 Unauthorized 用户未通过身份验证。需要有效的用户令牌
403 Forbidden 不允许该请求。例如,不允许用户删除项目。
404 Not Found 无法访问资源。例如,找不到资源的 ID。
405 Method Not Allowed 不支持该请求。
409 Conflict 已存在冲突资源。例如,创建一个名称已存在的项目。
412 请求被拒绝。如果在尝试删除资源时提供了 If-Unmodified-Since header,则可能会发生这种情况,该资源在两者之间进行了修改。
422 Unprocessable 无法处理该实体。
429 Too Many Requests 用户超出了应用程序速率限制
500 Server Error 在处理请求时,服务器出现问题。

分页

极狐GitLab 支持以下分页方式:

  • Offset-based 分页。这是默认方法,适用于所有端点。
  • Keyset-based 分页。添加到选定的端点,但正在逐步推出。

对于大型集合,出于性能原因,我们建议使用 Keyset-based 分页(如果可用)而不是 Offset-based 分页。

Offset-based 分页

有时,返回的结果跨越许多页面。列出资源时,可以传递以下参数:

参数 描述
page 页码(默认值:1)。
per_page 每页要列出的项目数(默认值:20,最大值:100)。

在以下示例中,我们每页列出 50 个命名空间:

curl --request GET --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/namespaces?per_page=50"
note存在用于 Offset-based 分页的最大 offset 许可的限制。您可以更改私有化部署实例中的限制。

每个响应都会返回 Link headers。它们将 rel 设置为 prevnextfirstlast,并包含相关的URL。请务必使用这些链接,而不是生成您自己的 URL。

在以下 cURL 示例中,我们将输出限制为每页三个项目 (per_page=3),并且我们请求属于 ID 为 9 的项目中,ID 为 8 的议题的评论的第二页(page=2):

curl --head --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/9/issues/8/notes?per_page=3&page=2"

响应为:

HTTP/2 200 OK
cache-control: no-cache
content-length: 1103
content-type: application/json
date: Mon, 18 Jan 2016 09:43:18 GMT
link: <https://gitlab.example.com/api/v4/projects/8/issues/8/notes?page=1&per_page=3>; rel="prev", <https://gitlab.example.com/api/v4/projects/8/issues/8/notes?page=3&per_page=3>; rel="next", <https://gitlab.example.com/api/v4/projects/8/issues/8/notes?page=1&per_page=3>; rel="first", <https://gitlab.example.com/api/v4/projects/8/issues/8/notes?page=3&per_page=3>; rel="last"
status: 200 OK
vary: Origin
x-next-page: 3
x-page: 2
x-per-page: 3
x-prev-page: 1
x-request-id: 732ad4ee-9870-4866-a199-a9db0cde3c86
x-runtime: 0.108688
x-total: 8
x-total-pages: 3

其它分页 headers

返回以下更多其它分页 headers:

Header 描述
x-next-page 下一页的索引。
x-page 当前页面的索引(从 1 开始)。
x-per-page 每页的项目数。
X-prev-page 上一页的索引。
x-total 事项总数。
x-total-pages 总页数。

Keyset-based 分页

Keyset-based 分页允许更有效地检索页面,并且与 Offset-based 分页相比,运行时独立于集合的大小。

此方法由以下参数控制:

参数 描述
pagination keyset(启用 keyset 分页)。
per_page 每页要列出的项目数(默认值:20,最大值:100)。

在以下示例中,我们每页列出 50 个项目,按 id 升序排列。

curl --request GET --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects?pagination=keyset&per_page=50&order_by=id&sort=asc"

响应 headers 包含指向下一页的链接。例如:

HTTP/1.1 200 OK
...
Link: <https://gitlab.example.com/api/v4/projects?pagination=keyset&per_page=50&order_by=id&sort=asc&id_after=42>; rel="next"
Status: 200 OK
...

下一页的链接包含一个额外的过滤器 id_after=42,它排除了已经检索到的记录。

作为另一个示例,以下请求列出了每页 50 个群组,使用 Keyset-based 分页,按 name 升序排列:

curl --request GET --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups?pagination=keyset&per_page=50&order_by=name&sort=asc"

响应 header 包含指向下一页的链接:

HTTP/1.1 200 OK
...
Link: <https://gitlab.example.com/api/v4/groups?pagination=keyset&per_page=50&order_by=name&sort=asc&cursor=eyJuYW1lIjoiRmxpZ2h0anMiLCJpZCI6IjI2IiwiX2tkIjoibiJ9>; rel="next"
Status: 200 OK
...

下一页的链接包含一个额外的过滤器 cursor=eyJuYW1lIjoiRmxpZ2h0anMiLCJpZCI6IjI2IiwiX2tkIjoibiJ9,它排除了已经检索到的记录。

过滤器的类型取决于使用的 order_by 选项,我们可以有多个额外的过滤器。

cautionLinks header 在 14.0 版本中被删除,以符合 W3C Link 规范Link header 添加于 13.1 版本,并且应该作为替代者被使用。

当到达集合的末尾并且没有要检索的其它记录时,Link header 不存在并且结果数组为空。

我们建议仅使用给定的链接来检索下一页,而不是构建您自己的 URL。除了显示的 header 外,我们不暴露更多的分页 header。

仅选定资源和排序选项支持 Keyset-based 的分页:

资源 选项 可用性
项目 order_by=id 经过身份验证和未经身份验证的用户
群组 order_by=name, sort=asc 仅限未经身份验证的用户

分页响应 headers

出于性能原因,如果查询返回超过 10,000 条记录,系统不会返回以下 headers:

  • x-total
  • x-total-pages
  • rel="last" link

路径参数

如果端点具有路径参数,则文档会使用前面的冒号显示它们。

例如:

DELETE /projects/:id/share/:group_id

:id 路径参数需要替换为项目 ID,:group_id 需要替换为群组的 ID。不应包含冒号 :

对于项目 ID 为 5且群组 ID 为 17 的项目,生成的 cURL 请求为:

curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/share/17"

必须遵循需要进行 URL 编码的路径参数。如果不匹配,则它与 API 端点不匹配并以 404 响应。如果 API 前面有东西(例如 Apache),请确保它不会解码 URL 编码的路径参数。

命名空间路径编码

如果使用命名空间 API 请求,请确保 NAMESPACE/PROJECT_PATH 是 URL 编码的。

例如,/%2F 表示:

GET /api/v4/projects/diaspora%2Fdiaspora

项目的路径不一定与它的名称相同。项目的路径可在项目的 URL 或项目的设置中找到,位于 通用 > 高级 > 更改路径 下。

文件路径、分支和标签名称编码

如果文件路径、分支或标签包含 /,请确保它是 URL 编码的。

例如,/%2F 表示:

GET /api/v4/projects/1/repository/files/src%2FREADME.md?ref=master
GET /api/v4/projects/1/branches/my%2Fbranch/commits
GET /api/v4/projects/1/repository/tags/my%2Ftag

请求负载

API 请求可以使用作为查询字符串或负载主体发送的参数。GET 请求通常发送查询字符串,而 PUT 或 POST 请求通常发送有效负载正文:

  • 查询字符串:

    curl --request POST "https://gitlab/api/v4/projects?name=<example-name>&description=<example-description>"
    
  • 请求有效负载 (JSON):

    curl --request POST --header "Content-Type: application/json" \
         --data '{"name":"<example-name>", "description":"<example-description>"}' "https://gitlab/api/v4/projects"
    

URL 编码的查询字符串有长度限制。太大的请求会导致 414 Request-URI Too Large 错误消息。可以通过使用负载主体来解决。

编码 arrayhash 类型的 API 参数

您可以使用 arrayhash 类型参数请求 API:

array

import_sourcesarray 类型的参数:

curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
-d "import_sources[]=github" \
-d "import_sources[]=bitbucket" \
"https://gitlab.example.com/api/v4/some_endpoint"

hash

override_paramshash 类型的参数:

curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
--form "namespace=email" \
--form "path=impapi" \
--form "file=@/path/to/somefile.txt" \
--form "override_params[visibility]=private" \
--form "override_params[some_other_param]=some_value" \
"https://gitlab.example.com/api/v4/projects/import"

哈希数组

variablesarray 类型的参数,包含哈希键/值对 [{ 'key': 'UPLOAD_TO_S3', 'value': 'true' }]

curl --globoff --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
"https://gitlab.example.com/api/v4/projects/169/pipeline?ref=master&variables[0][key]=VAR1&variables[0][value]=hello&variables[1][key]=VAR2&variables[1][value]=world"

curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
--header "Content-Type: application/json" \
--data '{ "ref": "master", "variables": [ {"key": "VAR1", "value": "hello"}, {"key": "VAR2", "value": "world"} ] }' \
"https://gitlab.example.com/api/v4/projects/169/pipeline"

id vs iid

一些资源有两个名称相似的字段。例如,议题、合并请求和项目里程碑。 这些字段是:

  • id:在所有项目中唯一的 ID。
  • iid:此外,在单个项目范围内唯一的内部 ID(显示在 Web UI 中)。

如果资源同时具有 iid 字段和 id 字段,则通常使用 iid 字段而不是 id 来获取资源。

例如,假设一个具有 id: 42 的项目存在 id: 46iid: 5 的议题。 在这种情况下:

  • 检索议题的有效 API 请求是 GET /projects/42/issues/5
  • 检索议题的无效 API 请求是 GET /projects/42/issues/46

并非所有具有 iid 字段的资源都由 iid 获取。有关使用哪个字段的指导,请参阅特定资源的文档。

数据验证和错误报告

使用 API 时,您可能会遇到验证错误,在这种情况下,API 会返回 HTTP 400 错误。

此类错误出现在以下情况:

  • 缺少 API 请求的必需属性(例如,未给出议题的标题)。
  • 属性未通过验证(例如,用户 bio 太长)。

当缺少某个属性时,您会收到如下信息:

HTTP/1.1 400 Bad Request
Content-Type: application/json
{
    "message":"400 (Bad request) \"title\" not given"
}

发生验证错误时,错误消息会有所不同。它们包含验证错误的所有详细信息:

HTTP/1.1 400 Bad Request
Content-Type: application/json
{
    "message": {
        "bio": [
            "is too long (maximum is 255 characters)"
        ]
    }
}

这使得错误消息更具机器可读性。格式可以描述如下:

{
    "message": {
        "<property-name>": [
            "<error-message>",
            "<error-message>",
            ...
        ],
        "<embed-entity>": {
            "<property-name>": [
                "<error-message>",
                "<error-message>",
                ...
            ],
        }
    }
}

未知路由

当您尝试访问不存在的 API URL 时,您会收到 404 Not Found 消息。

HTTP/1.1 404 Not Found
Content-Type: application/json
{
    "error": "404 Not Found"
}

在 ISO 8601 日期中编码 +

如果您需要在查询参数中包含 +,则可能需要使用 %2B,因为 W3 建议导致 + 被解释为空格。例如,在 ISO 8601 日期中,您可能希望包含 ISO 8601 格式的特定时间,例如:

2017-10-17T23:11:13.000+05:30

查询参数的正确编码是:

2017-10-17T23:11:13.000%2B05:30

速率限制

有关速率限制设置的管理员文档,请参阅 速率限制

内容类型

GitLab API 默认支持 application/json 内容类型,尽管一些 API 端点也支持 text/plain

在 13.10 及更高版本中,API 端点默认不支持 text/plain,除非明确记录。