Travis CI API 文档

超媒体和可发现性

Travis CI API 的第 3 版严格来说不符合任何超媒体规范,但其架构借鉴了 超媒体作为应用状态的引擎 (HATEOAS)

总的来说,这意味着

  • 客户端可以通过首先读取 API 根目录下的主文档来访问 API,该文档包含可用资源列表
  • 列表中的每个资源都包含操作,包括允许的 HTTP 动词、可能的资源属性和 URI 模板
  • 客户端可以使用这些操作来访问特定资源
  • 每个资源都包含元数据,以方便导航到相关资源

所有这些意味着,只要对资源链接方式有一定的了解,就可以构建一个通用的客户端来导航 API。这种客户端无需更新即可处理服务器端的变化。

API 格式文档 包含元数据的完整列表,但这里有一个快速示例描述资源之间的链接。元数据键以 @ 字符开头。

{
  "@type": "repository",
  "@href": "/repo/1",
  "id":    1,
  "owner": {
    "@type": "organization",
    "@href": "/org/2",
    "id":    2
  }
}

上面的存储库可以通过其 @href 访问,存储库的拥有者是一个组织,该组织也具有 @href

即使没有编写通用客户端的目标,API 的约定也可以帮助客户端进行资源发现。让我们来看一个例子。

假设我们想要找出存储库默认分支上最近的构建是否成功。我们需要

  1. 弄清楚如何请求存储库数据
  2. 找出存储库的默认分支
  3. 找出该分支上的最后一个构建

请注意,以下请求不包含身份验证头,并且某些响应为了清晰起见已缩写。

首先,我们读取主文档以了解 API 提供了哪些资源。

curl -H "Travis-API-Version: 3" https://api.travis-ci.com/
{
  "@type":     "home",
  "@href":     "/",
  "resources": {
    "repository": {
      "@type":    "resource",
      "actions":  {
        "find":   [
          {
            "@type":          "template",
            "request_method": "GET",
            "uri_template":   "/repo/{repository.id}{?include}"
          },
          {
            "@type":          "template",
            "request_method": "GET",
            "uri_template":   "/repo/{repository.slug}{?include}"
          }
        ]
      }
    }
  }
}

响应中包含一个名为 repository 的资源,该资源具有 find 操作。此操作具有两个模板,它们告诉客户端如何发出 GET 请求,将 URI 的一部分替换为存储库的 ID 或 slug。模板还包含一个可选的 include 参数,此参数在 急切加载 中没有涵盖。

我们不知道存储库的 ID,但我们从 Travis CI 和 GitHub 上的 URL 中知道它的 slug:travis-ci/travis-web。这足以请求有关存储库的更多数据。

将 slug 传递给 API 时,始终需要 对其进行编码,因此我们将 travis-ci/travis-web 中的 / 替换为 %2F

curl -H "Travis-API-Version: 3" \
     -H "Authorization: token xxxxxxxxx" \
    https://api.travis-ci.com/repo/travis-ci%2Ftravis-web

响应包含有关存储库的信息,包括 default_branch

{
  "@type":           "repository",
  "@href":           "/repo/269284",
  "@representation": "standard",
  "id":              269284,
  "name":            "travis-web",
  "slug":            "travis-ci/travis-web",
  "description":     "The Ember web client for Travis CI",
  "owner":           {
    "@type":         "organization",
    "id":            87,
    "login":         "travis-ci",
    "@href":         "/org/87"
  },
  "default_branch":  {
    "@type":           "branch",
    "@href":           "/repo/269284/branch/master",
    "@representation": "minimal",
    "name":            "master"
  }
}

嵌套资源具有 minimal 表示(参见 @representation)。这避免了 JSON 响应中的循环嵌套——想象一个包含拥有者的存储库,而拥有者又包含存储库列表,等等。它还可以减轻对数据库的负载。无论如何,嵌套资源的最小表示始终包含足够的信息供客户端在必要时发出更详细的请求。

由于 default_branch@typebranch,客户端可以参考主文档以确定 branch 可用的操作。但由于我们对存储库发出了 GET 请求,因此我们可以确定任何嵌套资源也可以通过 GET 访问,因此我们将导航到默认分支的 @href

curl -H "Travis-API-Version: 3" \
     -H "Authorization: token xxxxxxxxxx" \
    https://api.travis-ci.com/repo/269284/branch/master

在响应中,您可以看到最近的构建 (last_build) 是什么,以及它的状态是什么 ("passed")。

{
  "@type":            "branch",
  "@href":            "/repo/269284/branch/master",
  "@representation":  "standard",
  "name":             "master",
  "repository":       {
    "@type":           "repository",
    "@href":           "/repo/269284",
    "@representation": "minimal",
    "id":              269284,
    "name":            "travis-web",
    "slug":            "travis-ci/travis-web"
  },
  "default_branch":   true,
  "exists_on_github": true,
  "last_build":       {
    "@type":               "build",
    "@href":               "/build/208714092",
    "@representation":     "minimal",
    "id":                  208714092,
    "number":              "7631",
    "state":               "passed",
    "duration":            1162,
    "event_type":          "push",
    "previous_state":      "passed",
    "pull_request_title":  null,
    "pull_request_number": null,
    "started_at":          "2017-03-07T19:35:50Z",
    "finished_at":         "2017-03-07T19:40:56Z"
  }
}

要获取有关该构建中作业的更多信息,请继续沿着 @href 链接进行操作。

如果您想立即尝试一下,请查看 API 资源管理器