HTTP APIs 设计/规范指南

根据REST APIs的成熟度模型 ,此规范关注的是Level 2的APIs。 REST APIs 成熟度模型

1 设计指南

HTTP APIs主要由四部分组成:HTTP,URL,资源资源的表述(JSON)。资源的表述格式通常都采用JSON,故而后面就使用JSON代指资源的表述。根据这些组成部分,按照以下3个步骤设计APIs:

  1. 基于资源设计APIs。
  2. 基于URL标识资源
  3. 基于JSONHTTP操作URL标识的资源

1.1 基于资源设计API

设计HTTP APIs的首要任务是识别出业务领域中存在的资源。资源是对服务端提供的服务进行分解、组合后的一个被命名的抽象概念。

有一个很重要的点需要明确一下:资源≠数据表,它们两个之间并没有直接的映射关系。如果直接把数据存储结构映射为资源,则只会让资源无法有效的表达业务需要,也会造成资源本身和底层存储的紧耦合。

资源的设计是以名词为中心的。比如今天的天气是一个资源;而获取今天的天气则不是,它代表的是对今天的天气资源的一个读取操作。基于此我们可以抽象出来一个天气的资源。

1.2 基于URL标识资源

识别出资源后,则需要为其分配一个URL进行标识。

  1. 一个资源可以有多个URL
  2. 一个URL只能标识一个资源

总结来说就是资源:URL的关系就是1:N的关系。

比如上面提到的天气今天的天气这两个资源,可以用如下的URL进行标识。

资源 URL
天气 /weathers
今天的天气 /weathers/today
今天的天气 /weathers/2018-04-01,今天是2018-04-01

资源体现在URL中的Path部分;如果资源代表的是一个集合,则以复数的形式出现。

资源存在子资源的情况下,可以把子资源提升为顶层的资源。比如有一个订单资源/orders/{order_id},订单中包含2件物品。

# 不推荐 单个子资源
/orders/{order_id}/items/{item_id}

# 推荐 单个子资源
/order-items/{order_item_id}

# 推荐 子资源集合
/orders/{order_id}/items

1.3 基于JSONHTTP操作URL标识的资源

在标识出资源以后,就可以使用HTTP通过JSON来操作资源了。

  1. 使用HTTP Method来映射对资源的操作请求(CRUD或者其他)。
  2. 使用HTTP Header携带请求/响应所需的元数据信息。
  3. 使用HTTP Stauts Code代表HTTP协议层面的响应状态。
  4. 使用JSON作为数据交换格式。

2 规范指南

2.1 通用部分

  1. HTTP Method 规范
  2. HTTP Header 规范
  3. HTTP Stauts Code 规范
  4. URL 规范
  5. JSON 规范
  6. 命名(URL和JSON)规范
  7. 日期和时间格式化 规范
  8. 国际化 规范

2.2 API版本化

Level 2的HTTP APIs中,虽然我们推荐也努力使得我们的APIs不做不兼容的改动,但是依然无法彻底的避免不兼容的升级。这就使得我们不得不进行对APIs进行版本管理。通常有以下3种方案:

  1. URL
    GET http://api.linianhui.com/v1/resources HTTP/1.1
  2. Request Header
    GET http://api.linianhui.com/resources HTTP/1.1
    Api-Version: v1
  3. Request Header (Accept Header)
    GET http://api.linianhui.com/resources HTTP/1.1
    Accept: application/vnd.v1+json

Level 2中优先推荐使用方案1。理由是其更直观,便于实现,便于日志追踪。

2.3 错误处理

虽然HTTP Stauts Code4xx5xx的状态码来表示哪里出错了,但是其代表的只是HTTP协议层面的错误描述,它无法提供和业务相关的更具体错误描述。基于此种情况,我们需要设计一套描述业务层面错误的数据结构:

[
  {
    "error": "user_name", "message": "用户名不能为空。" }, { "error": "age", "message": "用户年龄不能小于0。" } ]
  1. 这个数据结构仅在状态码为4xx5xx出现的时候才会使用;2xx的时候则不包含此数据结构。
  2. error字段可以是一些出错的字段名、某一错误类别(比如no_permission)等等。
    [
      {
        "error": "no_permission", "message": "没有user.delete的权限" } ]

2.4 Request 公共查询参数

参数用途 参数名 取值范围
分页 page
page_size
>=1
排序 sort {field_name}|{asc|desc},{field_name}|{asc|desc}
区间 {field_name}_before
{field_name}_after
无要求
时间 {field_name}_at 无要求

示例:

GET /users?page=2&page_size=10&sort=name,age|desc&created_at_after=2018-01-01&created_at_before=2018-06-01 HTTP/1.1

上面的查询代表的含义:按照name升序和age倒序的排序方式;获取created_at时间位于2018-01-012018-06-01区间内;按照每页10条数据,获取第2页的数据。

2.5 Response 分页数据结构

在分页请求的时候,API会返回分页后的数据和分页的信息。

{
  "page": 2,
  "page_size": 10, "total_count": 100, "items":[ {...}, {...}, ] }

3 示例

... 待补充

参考资料

PayPal的API设计指南:https://github.com/paypal/api-standards

REST架构风格的出处:架构风格与基于网络的软件架构设计(by Fielding, R.)论文。

  1. 英文版: https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm
  2. 中文版: http://www.infoq.com/cn/minibooks/web-based-apps-archit-design
  3. 本人的解读REST系列博客:http://www.cnblogs.com/linianhui/category/774322.html

HTTP APIs 四大组成部分(HTTP,URI,MIME,JSON)

  1. HTTP/1.1 ( RFC7230-7235 ) :https://tools.ietf.org/html/rfc7230
  2. URI ( RFC 3986 ) :https://tools.ietf.org/html/rfc3986
  3. MIME ( RFC 2387 ):https://tools.ietf.org/html/rfc2387
  4. JSON : http://json.org/

Hypermedia

  1. JSON Schema: http://json-schema.org/

URL模板

  1. URI Template ( RFC6570 ) :https://tools.ietf.org/html/rfc6570

时间日期格式化

  1. Date and Time Formats - ISO 8601:https://www.w3.org/TR/NOTE-datetime
  2. Date and Time on the Internet: Timestamps ( RFC 3339 ) :https://tools.ietf.org/html/rfc3339#section-5.6

国际化

  1. https://www.iso.org/iso-3166-country-codes.html
  2. https://www.iso.org/iso-4217-currency-codes.html
  3. https://www.iso.org/iso-639-language-codes.html

REST APIs 成熟度模型:https://martinfowler.com/articles/richardsonMaturityModel.html

猜你喜欢

转载自www.cnblogs.com/gongap/p/9337950.html
今日推荐