从超文本到超数据|
15
14
1
REST
式编程和超媒体
按照
W3C
的定义,
Web
是“由链接连通的资源组成的网络信息空间”。这个信息空间
由分布在世界各地的多个信息系统共用,其他系统和代理在里面创建、获取、解释、解
析和推导资源。
因此,
Web
架构起来的是网络化分布式超媒体信息系统,客户端通过
URI
“调用”资源。
资源的状态通过一些广为人知的数据格式(
HTML
XML
CSS
PNG
、脚本)呈现的
资源表述传送。
在计算机科学领域,对分布式系统的研究正盛。其实,几乎所有新奇的事物都涉及分
布式系统,例如激增的
Web
应用,目前发展迅猛的移动计算,以及物联网(
Internet of
Things
IoT
)。
分布式系统大致可以定义为“若干独立计算机的集合,这些计算机对于用户来说就像是
单个相关系统”。
上述定义摘自
Andrew S. Tanenbaum
Maarten Van Steen
合著的《分布式系统原理
与范型(第
2
版)》。这本书是分布式系统的重要著作,让读者理解了分布式开发
的过去、现在和未来。
分布式系统的重要特点是,单个组件之间的区别,以及组件之间通信的方式对最终用户
来说几乎完全是透明的。只要实现外部通信协
议和接口时遵守规范,这一点对各个组件
的内部组织方式也成立。
因此,组件能独立自主地运作,通过交换信息还能与另一个组件协作。所以,不管何时
何处,假想的用户都能以统一的一致方式与分布式系统交互。
基本上,这一特点有利于分布式系统伸缩。
设计理念
REST
是为
Web
而生的,也建构在这个分布式系统之上。任何分布式系统的主要目标都
是让远程资源易于访问。
因此,设计
REST
时有意降低了门槛,而且兼顾简单性,以此促进用户采用,并提高开
发速度。
从超文本到超数据|
15
14
1
Web
设计的所有协议都是文本协议。
Web
组件之间的通信可以使用现有的网络工具和
底层协议测试。
此外,
REST
还能按需扩展。
Web
是网际应用,也就是说最初设计
Web
时没有考虑中央
集权。无政府的伸缩性和独立开发曾是(现在仍是)
Web
架构的两个核心特征。
REST
让超媒体应用成为可能。应用控制的信息内嵌在表述或上一层中。
REST
式架构
REST
式架构的一些约束继承自多个网络化分布式架构风格。
REST
式架构中,客户端和服务器是正交的,即二者的关注点和功能完全隔离,用户
逻辑完全移到客户端,而为了提高伸缩性,服务器组件则保持简单。
这样隔离还有个好处:只要这两个组件遵守通信协议和既定的接口,二者可以独立开发
和演进。
REST
式架构中,各个请求是独立处理的。这意味着,服务器要架构成无状态的,而
且请求不能利用任何既存的上下文,必须携带所需的全部信息,这样服务器才能理解并
处理。
此外,还要标明响应能否缓存。如果能缓存,为了提高网络效率(即缓存数据,减少往
返通信),客户端可以存储并重用数据。
REST
利用了组件之间的统一接口思想。这种简单的交互方式可以简化架构和设计抉择。
组件的内部实现与提供的服务隔开,这样有利于独立演进和开发。
REST
架构是分层的。这种分层系统根植于网络化架构和一般的软件开发中。
开发分层架构有几个优点。主要优点是,简化了系统的整体设计,因为各个组件只能“看
到”并操作与其直接交互的那层。
REST
引入的最后一个约束是按需编程。在
REST
式架构中,客户端可以下载并执行脚
本中的代码。这种方式提高了系统的扩展性,还简化了客户端的架构,很多功能无需事
前实现,而是留待以后需要时再增加。
REST
架构的核心元素是数据、组件和连接器。
REST
定义中所说的数据是具体的资源和交换的表述。组件就是我们熟知的客户端、源
服务器和各个中间方,可以通过连接器通信和交换消息。连接器专门用于在
REST
从超文本到超数据|
17
16
1
接口与其他类型的接口之间通信。例如,
REST
式服务可以通过
REST
连接器与不具备
REST
接口的数据库通信。
这三个元素都可以用来定义架构视图,这是一种抽象,有助于理解
REST
组件交互和通
信的方式。
一个视图描述架构中的一个分层。定义分层或视图的原因与以前围绕客户端和服务器这
两个概念进行的争论有关。在
HTTP
中,一个组件可以作为某个调用的服务器,也能作
为另一个调用的客户端(详情参见附录)。因此,从客户端和服务器的角度描述架构不
太理想。
有时,为了描述架构视图,我们会假设应用或客户端软件的最终目标是访问数据库中的
数据。这里,我们要考虑到三个分层:
接口层。
过程层。
数据层。
REST
架构中的确有这三层,不过使用
REST
核心元素描述
REST
架构视图更方便。
过程视图
REST
架构的过程视图描述一次通信中数据在客户端和服务器之间的流动过程。用户代
理向服务器发起请求,消息在网络中流动,经由一系列中间设备处理。中间设备有各种
用途,例如降低延迟、封装过时的服务、提高安全和均衡流量。在
REST
架构中,通信
过程中的任何一点都可以添加中间设备,而且组件之间的接口无需做任何改动。
前文说过,
REST
架构风格有利于独立部署,能提升组件和交互的伸缩性,以及接口的
普适性。客户端与服务器之间的消息流动完全是动态的。这一点有两个影响。第一个影响,
也是最明显的,请求消息的流动路径可能与响应消息的流动路径不同(见图
1-2
)。第
二个影响是,为了按路线发送消息,各个组件不一定非得知道整个网络拓扑结构。
从超文本到超数据|
17
16
1
代理
请求
隧道
网关
响应
源服务器用户客户端
互联网
1-2
请求和响应消息可能经由任意个中间设备
连接器视图
REST
架构的连接器视图在某种程度上等同于接口层,描述的是组件之间真正的通信。
因为
REST
是对
Web
架构的抽象,所以通信并不限于特定的协议。
REST
指定的是组件
之间交互的范围和实现组件所需的假设。
例如,虽然
Web
使用的传送协议是
HTTP
,但是
Web
架构还可以包含使用其他协议(如
FTP
)实现的服务。
REST
把与那些服务的交互委托给
REST
连接器处理。
REST
连接器
负责连接并联的其他(非
REST
)架构。
这一点保证了接口的普适性,确保各种各样的组件能完美通信(见图
1-3
)。
用户客户端
请求
互联网
响应
源服务器
1-3
REST 连接器能与非 REST 服务交互
让不同的组件之间易于通信
从超文本到超数据|
19
18
1
数据视图
架构的数据视图涉及应用的状态。
REST
是为分布式信息系统设计的架构风格,因此
REST
式应用可以不精确地定义为,根据用户输入执行某些特定任务的信息和控制方案
体系。
显然,这一定义包含很多不同的应用,例如在线字典、订票服务、社交网络网站和视频
流服务。这些应用都定义了一些目标,交给底层系统执行。
应用中的组件相互合作,完成这些目标。交换用于控制语义的消息时,或者交换完整的
资源表述时,组件都有交互。消息的体积各异。
组件之间常见的交互方式是,发起请求,获取资源的表述,
HTTP
中的
GET
方法(见
1-4
)。响应接收到的表述包含
REST
式资源的全部控制状态。
REST
的目标之一是,不让服务器维护当前请求之外的任何客户端状态。这样能提升服
务器的伸缩性,不过各个请求都是独立的,与前一个或后一个无关。
因此,应用状态要在即将发出的请求中定义,任何相连组件的拓扑结构、任何连接器中
现有的请求,以及资源表述的数据流负责响应请求。
用户客户端
请求
响应
源服务器
1-4
客户端发起一个 HTTP GET 请求
从服务器返回的响应中收到一个 HTML 文档
用户代理收到资源表述后可能会使用部分应用状态处理资源表述。
如果应用没有未处理完的请求,那么应用处于稳定状态。用户感知的性能由连续的稳定
状态之间的时间间隔衡量。
因为应用的控制状态在所请求的资源表述中,所以当务之急是获取第一个表述。获得第
一个表述之后,用户可以通过链接获取其他资源表述,然后直接处理控制状态。

Get RESTful Rails Development (中文版) now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.