RESTful API 设计指导

1. RESTful 简介

REST (Representational State Transfer) 翻作「表层状态转换」,是 Roy Thomas Fielding 在他的博士论文中提出的一种 API 设计风格。

表现层状态转换是根基于超文本传输协议(HTTP)之上而确定的一组约束和属性,是一种设计提供万维网络服务的软件构建风格。匹配或兼容于这种架构风格(简称为 REST 或 RESTful)的网络服务,允许客户端发出以统一资源标识符访问和操作网络资源的请求,而与预先定义好的无状态操作集一致化。因此表现层状态转换提供了在互联网络的计算系统之间,彼此资源可交互使用的协作性质(interoperability)。
—— wikipedia

当今互联网无处不在,现实需求日益复杂,为适应这种复杂性,技术不断革新。传统的 B/S 架构中,前后端分离是大势所趋,而这种分离正式基于 API 模型,由于 RESTful 的诸多便利,越来越多的公司开始拥抱 RESTful,如 Github、Google 等都大量使用这种风格的 API,掌握 RESTful API 成为了一个后端程序员必备的基本技能。

2. API 设计

RESTful API 是基于 HTTP 之上的一种设计风格,按照 HTTP 请求的基本组成将 RESTful API 分为如下几个模块:

2.1 协议

为保证数据的传输安全,推荐使用 HTTPS 协议

2.2 域名与版本

API 域名有两种形式可选择:

API 版本通常页有两种形式

2.3 资源操作

使用 HTTP 方法表示资源的操作

HTTP 方法 对应数据库操作 解释
GET SELECT 获取 URI 表示的资源(retrive),不产生副作用,对资源属性没有改变
POST INSERT 创建资源
PUT UPDATE 更新资源,客户端提供完整资源
PATCH UPDATE 更新资源的部分属性,客户端只提供更新的部分属性
DELETE DELETE 删除 URI 定位到的资源

2.4 资源路径——URL

资源路径的设计是 RESTful API 的核心,资源是 HTTP 协议对数据的抽象,一个资源可简单理解为数据库中的一张表。URL (统一资源定位符)是用于标识资源的字符串,资源如果可数则使用名词复数表示,否则使用单数表示,以用户users为例,

  • 获取用户列表

    1
    GET /users
  • 获取具体用户

    1
    GET /users/:user_id

    /users/1 表示获取用户 id 为 1 的用户

  • 新增用户

    1
    POST /users
  • 修改用户

    1
    PUT /users/:user_id

    客户端(表单)应提供完整的用户信息

  • 修改用户的部分属性

    1
    PATCH /users/:user_id

    客户端提供要修改的用户属性

  • 删除用户

    1
    DELETE /users/:user_id

以上只是最基本的 URI 设计原则,但是在实际工程中,多个资源之间会存在关联关系,如在经典的博客系统中,存在「用户—文章—评论」存在如下关联关系:

  • 一篇文章必定有一个或多个作者
  • 一个评论必定属于具体的一篇文章

用如下方式可表示「查看某个用户发布的文章」:

1
GET /users/1/articles 	# 查看 user_id 为 1 的文章

2.5 URL 参数

URL 参数应该只是对资源的过滤,不应该有其他作用,一般可用于分页、排序和筛选

1
2
3
4
5
?limit=10:指定返回记录的数量
?offset=10:指定返回记录的开始位置。
?page=2&per_page=100:指定第几页,以及每页的记录数。
?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序。
?animal_type_id=1:指定筛选条件

2.6 HTTP 请求头

HTTP 请求头可以携带附加信息,如版本号、响应格式和 Token 等。

2.7 HTTP 状态码

HTTP 状态码是由三位整数组成的,分为 5 大系列

  • 1xx : 请求已被接受,等待进一步处理,一般不常用。

    在使用 websocket 的时候从 websocket 协议升级到 socket.io 协议时返回 101,表示转换协议。

  • 2xx: 请求成功

  • 3xx: 重定向

  • 4xx: 客户端错误

  • 5xx: 服务端异常

详细的 HTTP 状态码可参考维基百科RFC2616

3. 不符合 CURD 的操作

在实际生产中,并非所有的 HTTP 请求都符合资源的 CURD 操作,不符合常规资源 CURD 操作的请求一般有如下三种处理方法:

  • 增加动作,并使用 POST 方法执行动作

    如文章发布 POST /articles/:id/publish

  • 增加控制参数

    发布文章使用 PATCH 更改文章的 published 属性 PATCH /articles/:id?published=true

  • 把动作转化为资源

    GitHub 把「喜欢」这个动作转化为一个资源 star,因为喜欢是不可数的,所以使用单数表示,比如“喜欢”一个 gist,使用 PUT /gists/:id/star,“取消喜欢”使用 DELETE /gists/:id/star

4. REST 的优点

  • 可更高效利用 HTTP 缓存来提高响应速度
  • 通讯本身的无状态性可以让不同的服务器的处理一系列请求中的不同请求,提高服务器的扩展性
  • 浏览器即可作为客户端,简化软件需求
  • 相对于其他叠加在HTTP协议之上的机制,REST的软件依赖性更小
  • 不需要额外的资源发现机制
  • 在软件技术演进中的长期的兼容性更好

本文标题:RESTful API 设计指导

文章作者:Pylon, Syncher

发布时间:2019年02月21日 - 21:02

最后更新:2023年03月11日 - 17:03

原始链接:https://0x400.com/experience/practice/dev-restful-api-design/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。