Representative State Transfer(REST)是目前业界比较流行的一种系统架构设计风格。很多大公司内部没有专门的培训,但是比较统一的系统设计都会遵循一些REST的约束和框架。如果我们完全遵循REST来设计网络服务,那么这个网络服务也可以叫做RESTful的服务。想要彻底明白REST,需要先理清几个概念:
- 资源(Resources):在REST中,资源是客户端从服务器端所请求的数据,一般是服务器端通过请求中的信息往后端(数据库或其它后端服务器)查询得到的数据。
- 比如,用户在一个在线购物平台查询所有名称为“XYZ”的书籍商品。客户端发出请求后,服务器端对数据库查询所有名称为“XYZ”且类型为书籍的商品,即为该请求对应的资源。
- 有一点比较重要的是,一般资源和最终服务器返回的数据会有不同的文件格式或者内容。服务器会经过一些数据筛选、排序或者分类等处理,最后转化成一个特定格式再返回客户端。
- 超文本传输协议(HTTP):协议本身网络上到处可以查到。REST关注的主要是HTTP的几个请求方法(methods),POST,GET,PUT和DELETE。这四个方法分别对应REST中的Create,Read,Update和Delete(CRUD)方法。
- Simple Object Access Protocal(SOAP):有听说过有人把SOAP和REST相提并论,并试图在系统设计中比较两者优劣。SOAP正如其名是一个系统设计中数据交互的协议,而REST是一个系统设计风格,并不是一个层面的概念。SOAP有一些自己的特点,比如依赖XML格式,而REST并不会要求数据传输依赖任何一个文件格式(因为REST是一个风格而已)。
REST设计对系统有六个约束:
- 客户端-服务器端架构(Client-server architecture):系统对于任意一次请求必须符合这个架构,这也是分布式系统中常见的一个架构模式,具体定义网上可以搜到。
- 无状态(Statelessness):服务器端不应该存储客户端任何状态,比如session等。
- 可缓存(Cacheability):客户端、服务器端或者中间代理层都可以进行缓存,返回数据中需要提供缓存信息,包括能否缓存以及缓存条件等。缓存一方面可以降低服务器载荷,但另一方面也要保证客户端不会获取到旧数据。
- 统一接口(uniform interface):这个约束是REST和非REST设计的一个本质区别,使得服务器端可以满足不同客户端对同一资源的请求,前提是客户端遵循统一的接口。这个约束包括以下四个子条件:
- 请求中需包括资源识别信息,即服务器端可以通过请求中的URI等精准查询到资源,并通过处理后返回客户端。
- 客户端可以通过返回数据对请求的资源再进行修改,比如修改或者删除等。举个例子,客户端查询到商品A后,可以通过返回的数据再修改商品A。
- 请求中的信息必须可以自我诠释(self-descriptive),即服务器端可通过请求内信息完全理解客户端的业务上的要求。
- Hypermedia as the engine of application state (HATEOAS,不知如何翻译),即客户端可以通过返回数据中的链接等对更多的相关资源进行请求。
- 层级系统(layered system):客户端与服务器端的交互需要和服务器端的层级设计解耦,即客户端不应该担心请求是直接发送给终端服务器(end server)还是中间层。最大的好处就是提高了服务器端可扩展性,添加负载均衡器(load balancer)或者和更多的后端服务器交互都不会影响和客户端的交互。
- 支持可执行代码(Code on demand)(不知如何翻译):如果客户端需要,服务器端可以返回一段可执行代码,比如客户端的JavaScript代码等。这是唯一一个可选的约束。
在具体REST设计中,URL的设计也有一些规范:
- 用斜杠来表示层级关系递进,比如.../college/school/major/class
- 用单复数来表示是否为列表,比如.../colleges?type=public
- 保持高可读性,比如用减号分割单词等,.../college-student
- 使用查询语句(query)来进行过滤(filtering)
- 不可以在URL中直接写出请求的方法或者动作(action),比如不允许.../get-student?id=1。应该使用HTTP方法来表明请求的具体动作,比如.../student?id=1, http action = get
- 不可以在URL中使用文件扩展名
以上就是课本上的内容,然而在日常工作中我们公司也并没有完全遵循REST的所有约束,比如可缓存等(除非系统对延迟敏感度很高)。而且事实上很多工程师,甚至高级工程师(senior级别的)也并不大清楚REST的设计原则(当然,这个和个人水平有关)。了解一下REST设计自然是没有坏处的,根据实际需求设计出实用且可靠的系统才是最重要的。
参考内容: