一、概述
Representational State Transfer (REST) is a software architecture style consisting of guidelines and best practices for creating scalable web services. REST is a coordinated set of constraints applied to the design of components in a distributed hypermedia system that can lead to a more performant and maintainable architecture.
REST是一种软件架构风格,是创建可扩展web服务的指南和最佳实践。在分布式系统中提出一系列约束和规范,以创建高性能和可维护的架构。如果一个架构符合REST原则,就可以称它为RESTful架构。
二、概念
1、资源
所谓资源,就是网络上的一个实体,可以是一段文本、一张图片、一种服务等具体的存在。用URI(统一资源标识符)来指向资源,每种资源对应一个特定的URI。要想获取资源,访问该资源的URI即可。
2、表现层
网络实体(资源)可以有多种表现形式,其具体表现出来的形式,称为它的表现层。比如文本可以用txt格式表现,也可以使用HTML格式、XML格式、JSON格式表现。图片可以用JPG格式表现,也可以使用PNG格式表现。URI只代表资源的位置,它的表现形式应该在请求的头信息中指定。
3、状态转换
当客户端与服务器之间进行互动时,会涉及到数据和状态的变化。由于HTTP协议是一个无状态协议,客户端需要通过HTTP动作使服务器端发生状态转化。
三、约束
要想构建RESTful的架构,有以下几个约束:
- 使用客户端/服务器模型。
- 使用层次化的系统。
- 无状态。客户端在每次发送请求时都需要提供足够的信息。
- 可缓存。能够缓存请求,以尽量减少客户端和服务器之间的信息传输。
- 统一的接口。使用统一的接口来完成用户与服务之间以及各子系统之间的交互。
关于接口,有以下几个原则:
- 每个资源都拥有一个资源标识。
- 消息的自描述性。所传递的消息需要能够提供自身的足够信息。
- 资源的自描述性。所返回的资源需要能够描述自身,并提供足够的用于操作该资源的信息。
- HATEOAS。只可以通过服务端所返回各结果中所包含的信息来得到下一步操作所需要的信息。
四、设计原则
1、资源识别
REST中的API是以资源为中心,而不是以执行的动作为中心。通常所执行动作的对象被看成是系统中的资源。如果一个动作没有明确的操作对象,就需要考虑该动作产生了哪些影响或哪些状态发生了改变,发生变化的实体就是资源。
在抽象出资源的过程中,按照自顶向下的方式,首先识别出主要资源,然后识别主要资源的子资源,依次迭代。
判断一个资源定义是否合理,有以下几种方法:
- 对资源的CRUD是否有意义。
- 是否需要除CRUD之外的操作。
- 资源是否被整体使用。
2、资源的URL
当标识出一个资源之后,需要为资源分配对应的URL。一个URL主要由几部分组成:
- 协议,即HTTP或HTTPS。
- 域名,尽量将API部署在专有域名下。如果API很简单,不会进一步扩展,也可以放在主域名下。
- 相对路径,每个网址代表一种资源,所以只使用名词,而不使用动词。所用的名词通常与数据库对应,并且数据库通常都是记录的集合,所以API中的名词应该使用复数形式。如果API版本更迭,应该将API的版本号也放到URL中。
- 请求参数,即由“?”开始,并由“&”连接的多个键值对组成的字符串。
对于返回的记录数量很多的场合,API应该提供参数,过滤返回结果:
- ?Limit=10,指定返回记录的数量。
- ?offset=10,指定返回记录的开始位置。
- ?page=2&per_page=100,指定第几页,以及每页的记录数。
- ?sortby=name&order=asc,指定返回结果按照哪个属性排序,以及排序的升降顺序。
- ?type_id=1,指定过滤条件。
3、使用合适的动词
对资源的具体操作类型,由HTTP动词表示。
- GET(SELECT),从服务器获取资源。
- POST(CREATE),在服务器创建一个资源。
- PUT(UPDATE),更新服务器上的资源(客户端提供更新后的完整资源)。
- PATCH(UPDATE),更新服务器上的资源(客户端提供更新的属性)。
- DELETE(DELETE),删除服务器上的资源。
- HEAD,获取资源的元数据。
- OPTIONS,获取关于资源的哪些属性是可以改变的信息。
()内表示与动词等价的数据库操作。
4、使用标准的状态码
服务器向客户端返回的状态码和提示信息,具体可参见HTTP响应码。如果状态码是4xx,就应该向客户端返回出错信息。通常返回的信息中将error作为键名,出错信息作为键值。
5、选择适当的表示结构
服务器返回的数据格式,应该尽量使用JSON,避免使用XML。