1. 说明
REST(Representational State Transfer)指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是 RESTful。
目前的三种主流 Web 服务实现方式——远程过程调用(RPC),面向服务架构(SOA)以及表述性状态转移(REST),REST 方式与复杂的 SOAP 和 XML-RPC 比起来更加简洁,越来越多的 Web 服务开始采用 REST 风格设计和实现。例如,Amazon.com 提供接近 REST 风格的 Web 服务进行图书查找;雅虎提供的 Web 服务也是 REST 风格的。
远程过程调用(RPC)
远程过程调用为 Web 服务提供一个分布式函数/方法接口供用户调用。这是一种较传统的方式。通常,在 WSDL 中对 RPC 接口进行定义(类似于早期的XML-RPC)。本质上,RPC 方式利用一个简单映射,把用户请求直接转化成一个特定语言编写的函数/方法。现在,该方式已不再使用。
面向服务架构(SOA)
面向服务架构现在,业界比较关注的是遵从面向服务架构(Service-oriented architecture,SOA)来构建 Web 服务。该方式中,通讯是由消息驱动,而不再是某个动作(方法调用)。这种 Web 服务也称为“面向消息的服务”。
表述性状态转移(REST)
REST是从资源角度来观察整个网络,资源由通用资源标志符(Uniform Resource Identifier,URI)确定,客户端应用通过 URI 获取资源的表征,这些表征会使应用程序转变其状态。随着不断地获得资源表征,客户端应用也不断地转变其状态。
在我们当前开发中,绝大多数应用场景都是建议使用REST规范的,所以建议项目上的API设计,都要默认遵循RESTful风格。
2. HTTP协议
对于HTTP协议,我们既熟悉,又陌生。熟悉,是因为我们每天开发API服务,都是基于HTTP协议。陌生,是因为我们大多数人在API设计上,都没有完全考虑到HTTP协议的规范。
!>HTTP是基于客户端/服务端(C/S)的架构模型,通过一个可靠的链接来交换信息,是一个无状态的请求/响应协议。HTTP使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接。
一个基于HTTP协议消息,由如下部分组成:
- HTTP请求方法:HTTP1.0只有GET、POST、HEAD,HTTP1.1之后增加OPTIONS、PUT、PATCH、DELETE、CONNECT等。
- HTTP响应头:提供了关于请求,响应或者其他的发送实体的信息。
- HTTP状态码:HTTP状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用。1xx(信息,服务器收到请求,需要请求者继续执行操作)、2xx(成功,操作被成功接收并处理)、3xx(重定向,需要进一步的操作以完成请求)、4xx(客户端错误,请求包含语法错误或无法完成请求)、5xx(服务器错误,服务器在处理请求的过程中发生了错误)。
- content-type:告诉客户端实际返回的内容的内容类型。
我们来看一段HTTP GET请求和响应的报文:
请求报文
GET /users HTTP/1.1
uid: Kerry
User-Agent: PostmanRuntime/7.24.0
Accept: */*
Cache-Control: no-cache
Postman-Token: 4f23c891-9279-4e89-85c9-329b7c47262a
Host: localhost:8002
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
响应报文
HTTP/1.1 200 OK
Content-Type: application/json
Transfer-Encoding: chunked
Date: Thu, 26 Mar 2020 07:46:29 GMT
Keep-Alive: timeout=60
Connection: keep-alive
[{"id":41,"username":"Kerry","chinese_name":"吴晨瑞0329","email":"kerry.wu@definesys.com","birthday":"1995-08-18","department_id":1,"object_version":4,"created_by":"Kerry","created_date":"2020.03.08 18:15:14","last_updated_by":"kerry0325","last_updated_date":"2020.03.26 14:38:57","department_name":null}]
关于HTTP协议的详细介绍,建议查看菜鸟教程。
3. URL路径
路径又称"终点"(endpoint),表示API的具体网址。
- 服务器层面上,建议将API部署在专用域名之下,或主域名下。如:https://api.example.com 或 https://example.org/api/。
- 建议将API的版本号放入URL中,如:https://api.example.com/v1/ 。另一种做法是,将版本号放在HTTP头信息中,但不如放入URL方便和直观。Github采用这种做法。直接修改线上接口,会导致调用方报错,建议通过升版本号实现。
- 在RESTful架构中,每个网址代表一种资源,所以网址中不能有动词,只能有名词。名词可以是与数据库的表格名对应,也可以是与业务系统,或业务功能名称对应。
- 如果名词是与数据库的表格名对应的,API中的名词应该使用复数,其他情况则没必要。
- 按照资源的逻辑层级,对 URL 进行嵌套。
- 路径中的资源名称一律使用小写字母,如果名词由多个单词组成,则使用连字符”-“来连接单词。
-
API参数传递时,无论是基于path还是body,参数命名都统一用驼峰式命名。
举个经典的例子,有一个API提供动物园(zoo)的信息,还包括各种动物园里面动物的信息,则它的GET接口路径应该设计成下面这样。
<!-- 查询所有动物园信息 --> https://api.example.com/v1/zoo-mg/zoos <!-- 查询某个{ID}动物园的所有动物信息 --> https://api.example.com/v1/zoo-mg/zoos/{ID}/animals <!-- 分页查询某个{ID}动物园的猫科动物信息 --> https://api.example.com/v1/zoo-mg/zoos/{ID}/animals?class=猫科&page=1&pageSize=10
4. HTTP动词
对于资源的具体操作类型,由HTTP动词表示。
常用的HTTP动词有下面五个(括号里是对应的SQL命令)。
- GET(SELECT):从服务器取出资源(一项或多项)。
- POST(CREATE):在服务器新建一个资源。
- PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。
- PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。
- DELETE(DELETE):从服务器删除资源。
还有两个不常用的HTTP动词。
- HEAD:获取资源的元数据。
- OPTIONS:获取信息,关于资源的哪些属性是客户端可以改变的。
下面是一些例子。
- 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:删除某个指定动物园的指定动物
5. 接口返回
1 成功
状态码
状态码为2xx,这里建议都用200返回。
响应结果
针对不同操作,服务器向用户返回的结果应该符合以下规范。
- GET /collection:返回资源对象的列表(数组)
- GET /collection/resource:返回单个资源对象
- POST /collection:返回新生成的资源对象
- PUT /collection/resource:返回完整的资源对象
- PATCH /collection/resource:返回完整的资源对象
- DELETE /collection/resource:返回一个空文档
2 失败
状态码
状态码有 4xx 或 5xx ,如:500 INTERNAL SERVER ERROR、401 Unauthorized、404 NOT FOUND等。
响应结果
对于需要向用户返回出错信息的。我们定义,在返回的信息中将error作为键名,出错信息作为键值即可。
{
"error": "告知用户的错误原因"
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。