REST(Representational State Transfer) 是 Roy Fielding 博士在2000年他的博士论文「Architectural Styles and the Design of Network-based Software Architectures(PDF)」中提出来的一种软件架构风格。REST 服务与早前 Web Service 的 SOAP 和 XML-RPC 协议对比来讲更加简洁,现在越来越多的 Web 服务开始采用 REST 风格设计和实现。
Restful API 设计就是设计具有 REST 风格的 Web API。
一、名词解释
-
资源(resource):一个操作对象的抽象实例。例如:公交系统中的某张票卡(ticket),管理系统中的某个用户(user)等。
-
集合(collection):一种资源。使用资源的复数表示。例如:公交系统中的所有票卡(tickets),管理系统中的所有用户(users)等。
-
调用方(consumer):调用 API 的一方。HTTP 请求由调用方发起。也翻译成“消费者”、“客户端”、“应用”。
-
服务端(server):提供 API 服务的一方。HTTP 响应由服务端返回。也翻译成“服务”、“服务方”、“被调用方”。
-
接口(endpoint):一个 API。表现形式是 URL 地址,指向一个资源或一种资源。也翻译成“终点”、“端点”。英文中也有“entry point”的用法。
-
幂等性(idempotent):HTTP 的幂等性。指 API 无论调用一次还是多次,所产生的结果是一样的。
二、关于 URL 的设计
2.1. 使用 API 域
建议使用api
作为一级目录。好处是服务端可以方便扩展 API 以外的服务。例如,
https://example.com/api/... <-- 子域为API,返回数据是 json 形式
https://example.com/doc/... <-- 子域为文档,返回数据是 html 形式
另外一种设计是把api
作为二级域名。例如,
https://api.example.com <-- API地址,以下的 URL 全部是 API
https://doc.example.com <-- 文档地址,以下是 html 格式的文档
当网站很大时,api
也可以作为模块下的一级目录。例如,
https://example.com/shop/api/... <-- 商店子系统的API
https://example.com/shop/doc/... <-- 商店子系统的文档
https://example.com/shop/web/... <-- 商店子系统的页面
https://example.com/store/api/... <-- 仓库子系统的API
https://example.com/store/wiki/... <-- 仓库子系统的wiki页面
注:以api
命名不是必须的,但是使用api
来标识 API 的域会更容易理解。
2.2. 使用版本
建议在 URL 中包含 API 的版本号。好处是:1. API 升级不影响调用方的代码,2. 升级后的 API 可以不向前兼容。
https://example.com/api/v1/... <-- 第一版 API
https://example.com/api/v2/... <-- 第二版 API
另外,还有其他两种设计。
2.2.1. 使用 accept header 标识版本
调用方在 HTTP 请求的 header 中写明所需的 API 版本,服务端识别后,使用相应版本的 API 处理调用方的请求。
Accept: application/json+v1
2.2.2. 使用自定义的 HTTP header 标识版本
调用方在 HTTP 请求的 header 中加入自定义的 header 项来告诉服务端所调用的 API 版本。
X-Api-Version: 1
2.3. 资源的命名
2.3.1. 使用名词
/get <-- bad
/getTickets <-- bad
/tickets <-- good
2.3.2. 使用中横线或下划线
资源的名称中可以包含中横线(-)或下划线(_),在系统设计时应遵循统一的规则,即统一使用中横线(kebab-case rule)或统一使用下划线(snake_case rule)。
2.3.3. 使用小写
建议使用小写字母命名资源。在需要多个名词组合时,一般用中横线或下划线分隔,而不使用驼峰命名法(camelCase rule)。
/lockedAccount <-- bad
/locked-account <-- good
/locked_account <-- good
2.4. 使用集合表示资源种类,资源的 ID 标识的资源实例
/ticket <-- bad
/tickets <-- good,表示系统中的所有票卡
/tickets/1 <-- good,表示编号为1的票卡