REST API

与 GraphQL API 相比,REST API 存在的时间更长,开发人员可能更加熟悉。对于习惯传统 API 架构的开发人员来说,REST API 是个很好的选择。

兼容性指南

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

次要版本不明确,这样就允许稳定的 API 端点。可以在拥有相同版本号的 API 中添加新功能。

新功能和错误修复会与极狐GitLab 一起发布。除了附带的补丁和安全版本,极狐GitLab 在每个月的 22 日左右发布。 主要的 API 版本更改和整个 API 版本的删除与主要的极狐GitLab 版本同步完成。 。

版本之间的所有弃用和更改都会在文档中记录。

当前状态

只有 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

note在上面的示例中,将 gitlab.example.com 替换为 gitlab.com 以查询 JiHuLab.com (极狐GitLab SaaS)。 由于身份验证,访问可能会被拒绝。有关详细信息,请参阅身份验证

公开 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 进行身份验证:

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

  • 私有化部署的极狐GitLab:免费版、专业版和旗舰版。
  • 极狐GitLab SaaS:专业版和旗舰版。

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

如果身份验证信息无效或丢失,极狐GitLab 将返回带有 401 状态码的错误信息:

{
  "message": "401 Unauthorized"
}
note部署令牌不能与极狐GitLab 公共 API 一起使用。详情请参见部署令牌

OAuth 2.0 令牌

您可以使用 OAuth 2.0 令牌通过将其传递到 access_token 参数或 Authorization 标头来使用 API 进行身份验证。

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

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

在标头中使用 OAuth 2.0 令牌的示例:

curl --header "Authorization: Bearer OAUTH-TOKEN" "https://gitlab.example.com/api/v4/projects"

阅读更多关于极狐GitLab 作为 OAuth 2.0 提供者的内容。

note我们建议为 OAuth 访问令牌设置过期时间。您可以使用 refresh_token 参数刷新令牌。 集成可能需要在到期前更新以使用刷新令牌,这基于令牌端点响应中的 expires_in参数。 有关使用刷新令牌请求新访问令牌的示例,请参阅 OAuth 2.0 令牌文档。

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

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

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

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

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

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

您也可以使用个人、项目或群组访问令牌与 OAuth-compliant 标头一起使用:

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 功能。用户或管理员的密码或令牌可能是未知的,或者可能会随着时间的推移而改变。

有关详细信息,请参阅用户 API 文档。

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

禁用模拟

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

对于 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

所有 API 请求都支持您像另一个用户一样执行 API 请求,前提是您已通过 OAuth 或具有 sudo 范围的个人访问令牌的管理员身份验证。 API 请求通过模拟用户的权限进行执行。

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

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

分页

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

  • 基于偏移量的分页。这是默认方法,可用于所有端点。
  • 基于键集的分页。添加到选定的端点。

对于大型集合,出于性能原因,您应该使用键集分页(可用时)而不是偏移分页。

基于偏移量的分页

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

参数 描述
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偏移分页有一个允许的最大偏移量限制。您可以更改私有化部署实例中的限制。

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

对于 JiHuLab.com 用户,某些分页标题可能不会返回

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

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

其他分页标题

极狐GitLab 还返回以下额外的分页标头:

标头 描述
x-next-page 下一页的索引
x-page 当前页的索引(从 1 开始)
x-per-page 每页的项目数
x-prev-page 上一页的索引
x-total 项目总数
x-total-pages 页码总数

对于 JiHuLab.com 用户,某些分页标头可能不会返回

基于键集的分页

基于键集的分页允许更有效地检索页面,并且与基于偏移量的分页相比,运行时独立于集合的大小。

此方法由以下参数控制。 order_bysort 都是强制性的。

参数 是否必需 描述
pagination yes keyset(启用键集分页)
per_page no 每页列出的项目数(默认:20;最大:100
order_by yes 排序依据的列
sort yes 排序顺序(ascdesc

在下面的示例中,我们每页列出 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"

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

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,排除已检索的记录。

作为另一个示例,以下请求使用键集分页按 name 升序列出每页 50 个群组

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"

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

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 选项,我们可以有多个额外的过滤器。

caution极狐GitLab 14.0 中删除了 Links 标头,以便与 W3C Link 规范保持一致。 Link 标头已在极狐GitLab 13.1 中添加,用户可以使用。

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

您应该仅使用给定的链接来检索下一页,而不是构建您自己的 URL。除了显示的标头外,我们不会公开其他分页标头。

支持的资源

仅选定资源和排序选项支持基于键集的分页:

资源 选项 可用性
群组审计事件 order_by=idsort=desc 仅引入于 15.2 的经过身份验证的用户
群组 order_by=namesort=asc 仅未经过身份验证的用户
实例审计事件 order_by=idsort=desc 仅引入于 15.11 的经过身份验证的用户
作业 order_by=idsort=desc 仅引入于 15.9 的经过身份验证的用户
项目审计事件 order_by=idsort=desc 仅引入于 15.10 的经过身份验证的用户
项目 order_by=id 经过身份验证的和未经过身份验证的用户

分页响应标头

出于性能原因,如果查询返回超过 10,000 条记录,极狐GitLab 不返回以下标头:

  • 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"

哈希阵列

variables 是类型 array 的参数,该类型包括哈希键/值对 [{ '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 获取。 有关使用哪个字段的更多内容,请参阅特定资源的文档。

null vs false

在 API 响应中,一些布尔字段可以有 null 值。 null 布尔没有默认值,既不是 true 也不是 false。 极狐GitLab 将布尔字段中的 null 值视为 false

在布尔参数中,您应该只设置 truefalse 值(而不是 null)。

数据验证和错误报告

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

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

  • 缺少 API 请求的必需参数(例如,未给出议题的标题)。
  • 参数未通过验证(例如,用户简介过长)。

当缺少某个参数时,您会收到类似以下内容的消息:

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>",
                ...
            ],
        }
    }
}

未知路线

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

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

在 ISO 8601 日期中编码 +

由于将 + 解析为空格的 W3 推荐,如果您需要在查询参数中包含 +,您可能需要使用 %2B。 例如,在 ISO 8601 日期中,您可能希望包含 ISO 8601 格式的特定时间,例如:

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

查询参数的正确编码是:

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

客户端

许多非官方的极狐GitLab API 客户端可用于大多数流行的编程语言。如需完整列表,请参阅极狐GitLab 网站

速率限制

有关速率限制设置的管理员文档,请参阅速率限制。 有关 JiHuLab.com 专门使用的使用,请参阅 JiHuLab.com 特定速率限制

内容类型

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

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

解决被检测为垃圾邮件的请求

引入于极狐GitLab 14.9。

REST API 请求可以被检测为垃圾邮件。如果请求被检测为垃圾邮件并且:

  • 未配置验证码服务,则会返回错误响应。例如:

    {"message":{"error":"Your snippet has been recognized as spam and has been discarded."}}
    
  • 配置了验证码服务,您会收到有如下设置的响应:
    • needs_captcha_response 设置为 true
    • spam_log_idcaptcha_site_key 字段设置

    例如:

    {"needs_captcha_response":true,"spam_log_id":42,"captcha_site_key":"REDACTED","message":{"error":"Your snippet has been recognized as spam. Please, change the content or solve the reCAPTCHA to proceed."}}
    
  • 使用 captcha_site_key 通过适当的 CAPTCHA API 获取 CAPTCHA 响应值。 仅支持 Google reCAPTCHA v2
  • 使用 X-GitLab-Captcha-ResponseX-GitLab-Spam-Log-Id 标头集重新提交请求。
export CAPTCHA_RESPONSE="<CAPTCHA response obtained from CAPTCHA service>"
export SPAM_LOG_ID="<spam_log_id obtained from initial REST response>"
curl --request POST --header "PRIVATE-TOKEN: $PRIVATE_TOKEN" --header "X-GitLab-Captcha-Response: $CAPTCHA_RESPONSE" --header "X-GitLab-Spam-Log-Id: $SPAM_LOG_ID" "https://gitlab.example.com/api/v4/snippets?title=Title&file_name=FileName&content=Content&visibility=public"