本文主要参考阮一峰的 RESTful API 设计指南
1. 协议
API 与用户的通信协议,总是使用 HTTPs
2. 域名
应该尽量将 API 部署在专用域名下:
https://api.example.com
如果 API 很简单,不会有进一步扩展,可以考虑放在主域名下:
https://example.com/api/
3. 版本
应该将 API 的版本号放入 URL:
https://api.example.com/v1/
另一种做法是,将版本号放在 HTTP 头信息中,但不如放在 URL 方便和直观。(不过如果 API 放在主域名下呢?再加上版本号是否会显得 API 很冗余?)
4. 路径
在 RESTful 架构中,每个网址代表一种资源,所以网址中不能有动词,只能有名词,而且所用的名词往往和数据库中的表名对应。一般来说,数据库中的表都是同种记录的 "集合",所以 API 中的名词也应该使用复数。
举例来说,有一个 API 提供动物园(zoo)的信息,还包括各种动物和雇员的信息,则它的路径应该设计成这样:
https://api.example.com/v1/zoos
https://api.example.com/v1/animals
https://api.example.com/v1/employees
URI 中需要注意的几点:
- 不用大写
- 用中杠
-
不用下杠_
- 参数列表要 encode
- URI 中名词表示资源集合,使用复数形式
5. HTTP 动词
常用的 HTTP 动词有下面五个(括号里对应的 SQL 命令):
GET(SELECT):从服务器取出资源(一项或多项)
POST(CREATE):从服务器新建一个资源
PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整属性)
PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)
DELETE(DELETE):从服务器删除资源
下面是一些例子:
GET /zoos:列出所有动物园
POST /zoos:新建一个动物园
GET /zoos/ID:获取某个指定动物园的信息
PUT /zoos/ID:更新某个指定动物园的信息(提供该动物园的全部信息)
PATCH /zoos/ID:更新某个指定动物园的信息(提供该动物园的部分信息)
DELETE /zoos/ID:删除某个动物园
GET /zoos/ID/animals:列出某个指定动物园的所有动物
DELETE /zoos/ID/animals/ID:删除某个指定动物园的指定动物
RESTful 架构风格具有 统一接口 的特点,即使用不同的 http 方法表达不同的行为,不再出现类似 /zoos/add,/zoos/ID/delete 这样的形式。
在 RESTful 的标准中,PUT 和 PATCH 都可以用于修改操作,它们的区别是 PUT 需要提交整个对象,而 PATCH 只需要提交修改的信息。但是在我看来实际应用中不需要这么麻烦,所以我一律使用 PUT,并且只提交修改的信息。
关于 PUT 和 PATCH 的更多辩析,可以看 这里
6. 过滤信息
如果记录数量很多,服务器不可能将它们全部返回。API 应该提供参数,过滤返回结果:
?limit=10
?offset=10
?page=2&per_page=100
?sortby=name&order=asc
?animal_type_id=1
参数的设计允许存在冗余,即允许 API 路径和 URL 参数偶尔有重复。比如 GET /zoos/ID/animals 和 GET /animals?zoo_id=ID 的含义是相同的
7. 状态码
200 OK - [GET]:服务器成功返回请求的数据
201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功
204 NO CONTENT - [DELETE]:用户删除数据成功
400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改的操作
404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作
500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户无法判断发出的请求是否成功(该状态码是服务器自动生成返回的,不能手动将状态码返回 500)
有很多服务器将返回状态码一直设为 200,然后在返回 body 里面自定义一些状态码来表示服务器返回结果的状态码。由于 RESTful 是直接使用的 HTTP 协议,所以它的状态码也要尽量使用 HTTP 协议的状态码。
8. 错误处理
如果状态码是 4xx,就应该向用户返回出错信息。
{
error: "Invalid API key"
}
9. 返回结果
针对不同操作,服务器向用户返回的结果应该符合以下规范。
GET /collection:返回资源对象的列表(数组)
GET /collection/resource:返回单个资源对象
POST /collection:返回新生成的资源对象
PUT /collection/resource:返回完整的资源对象
PATCH /collection/resource:返回完整的资源对象
DELETE /collection/resource:返回一个空文档
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。