TSF HTTP API Guidelines

24th April 2021 at 10:29am

这里描述我在制订 TSF 容器 API 规范时总结的经验。

TODO:部分内容待补充

Request ID

在 HTTP 请求的头部带上 X-Request-ID,用来唯一标识一个请求。回包必须将该 X-Request-ID 以 HTTP 头形式原样带回。示例:

X-Request-ID: 921e2b45-83db-4ecd-b17a-2f7a7cf0bd0f

一些调研:

  • GET 请求无法带请求体,所以在请求体中(比如 JSON 结构中)放 request ID 并不合适
  • X-Request-ID 不在 HTTP 规范中,但是相对广泛使用(参考 Wikipedia
  • 有些代理服务器可能会 strip 掉这个头
  • Correlation IDs for microservices architectures 这篇描述了挺长篇幅,应该有有价值的内容,有时间看看

关于 API 请求成功时,是否返回 201 / 204 的问题

关于 201 (Created) / 204 (No Content) 回包可能没有回包,与 API 回包设计中 {"code", 0, "message": ""} 在设计上的冲突,需要考虑下。

按 ID 批量查询资源

API Handyman 的这篇 文章 给出了一个常见的 URL pattern 设计:

GET /resources?ids=ID1,ID2

其中有几点需要考量:

  1. 用逗号(,)作分隔符是否合适?
  2. 返回体的结构设计
  3. 分页及不存在的 ID 处理

用逗号作分隔符

根据这个 SO 回答,用逗号作分隔符是 OK 的。query component 指 URL 中 ?#(如果没有,则到 URL 末尾)的中间部分,这部分可以包含的字符有

  • a-z, A-Z
  • 0-9
  • / ? : @ ! $ & ' ( ) * + , ; = - . _ ~
  • percent-encoded characters

其中 , / 这些虽然叫作 reserved character,但是这里的 reserved 并不是不能用,而是说如果这些字符如果没有使用它的特殊含义(如作为分隔符),而是当作普通的字符串使用,那么你应该 percent-encode 它。

一些使用了 reserved character 的场景:

  • Google Drive 的文件查看功能:https://drive.google.com/viewerng/viewer?url=http://journals.plos.org/plosone/s/file?id=body.pdf
  • 电商网站中经常会看到 ,
  • 一些 OAuth 的 callback URL

返回体的结构设计

API Handyman 用的方案是:

{
  "ID1": {
    "status": "201",
    "headers": [
      {"header's name": "header's value"}
    ],
    "body": { "the": "response's body"}
  },
  "ID2": {
    "status": "400",
    "headers": [
      {"header's name": "header's value"}
    ],
    "body": { "the": "response's body"}
  }
}

这个结构更适合于创建多个对象时使用,而不适合在查询多个对象时。我觉得应该沿用列表页的回包结构:

{
  "data": {
    "totalCount": 5,
    "content": [
      {
        "id": "498e8220-5342-4277-b1cd-40caecbf9840",
        "name": "main-cluster"
      },
      {
        "id": "498e8220-5342-4277-b1cd-40caecbf9840",
        "name": "second-cluster",
      }
    ]
  },
  "code": 0,
  "message": ""
}

分页及不存在的 ID 处理

TODO: 不存在的 ID 会影响返回结构中的 totalCount,以及需要一种机制表达该元素不存在。后续考虑。