rest架构介绍

本文转自:理解本真的REST架构风格

REST架构风格架构约束

REST架构风格最重要的架构约束有6个

  • 客户-服务器(Client-Server)通信只能由客户端单方面发起,表现为请求-响应的形式。
  • 无状态(Stateless)通信的会话状态(Session State)应该全部由客户端负责维护。
  • 缓存(Cache)响应内容可以在通信链的某处被缓存,以改善网络效率。
  • 统一接口(Uniform Interface)通信链的组件之间通过统一的接口相互通信,以提高交互的可见性。
  • 分层系统(Layered System)通过限制组件的行为(即,每个组件只能“看到”与其交互的紧邻层),将架构分解为若干等级的层。
  • 按需代码(Code-On-Demand,可选)支持通过下载并执行一些代码(例如Java Applet、Flash或JavaScript),对客户端的功能进行扩展。

REST详解

REST究竟是什么?因为REST的内涵非常丰富,所以很难用一两句话解释清楚这个问题。

首先,REST是Web自身的架构风格。REST也是Web之所以取得成功的技术架构方面因素的总结。REST是世界上最成功的分布式应用架构风格(成功案例:Web,还不够吗?)。它是为 运行在互联网环境 的 分布式 超媒体系统量身定制的。互联网环境与企业内网环境有非常大的差别,最主要的差别是两个方面:

  • 可伸缩性需求无法控制:并发访问量可能会暴涨,也可能会暴跌。
  • 安全性需求无法控制:无法控制客户端发来的请求的格式,很可能会是恶意的请求。

而所谓的“超媒体系统”,即,使用了超文本的系统。可以把“超媒体”理解为超文本+媒体内容。

REST是HTTP/1.1协议等Web规范的设计指导原则,HTTP/1.1协议正是为实现REST风格的架构而设计的。新的Web规范,其设计必须符合REST的要求,否则整个Web的体系架构会因为引入严重矛盾而崩溃。这句话不是危言耸听,做个类比,假如苏州市政府同意在市区著名园林的附近大型土木,建造大量具有后现代风格的摩天大楼,那么不久之后世界闻名的苏州园林美景将不复存在。

上述这些关于“REST是什么”的描述,可以总结为一句话:REST是所有Web应用都应该遵守的架构设计指导原则。当然,REST并不是法律,违反了REST的指导原则,仍然能够实现应用的功能。但是违反了REST的指导原则,会付出很多代价,特别是对于大流量的网站而言。

要深入理解REST,需要理解REST的五个关键词:

  • 资源(Resource)
  • 资源的表述(Representation)
  • 状态转移(State Transfer)
  • 统一接口(Uniform Interface)
  • 超文本驱动(Hypertext Driven)

什么是资源?

资源是一种看待服务器的方式,即,将服务器看作是由很多离散的资源组成。每个资源是服务器上一个可命名的抽象概念。因为资源是一个抽象的概念,所以它不仅仅能代表服务器文件系统中的一个文件、数据库中的一张表等等具体的东西,可以将资源设计的要多抽象有多抽象,只要想象力允许而且客户端应用开发者能够理解。与面向对象设计类似,资源是以名词为核心来组织的,首先关注的是名词。一个资源可以由一个或多个URI来标识。URI既是资源的名称,也是资源在Web上的地址。对某个资源感兴趣的客户端应用,可以通过资源的URI与其进行交互。

什么是资源的表述?

资源的表述是一段对于资源在某个特定时刻的状态的描述。可以在客户端-服务器端之间转移(交换)。资源的表述可以有多种格式,例如HTML/XML/JSON/纯文本/图片/视频/音频等等。资源的表述格式可以通过协商机制来确定。请求-响应方向的表述通常使用不同的格式。

什么是状态转移?

状态转移(state transfer)与状态机中的状态迁移(state transition)的含义是不同的。状态转移说的是:在客户端和服务器端之间转移(transfer)代表资源状态的表述。通过转移和操作资源的表述,来间接实现操作资源的目的。

什么是统一接口?

REST要求,必须通过统一的接口来对资源执行各种操作。对于每个资源只能执行一组有限的操作。以HTTP/1.1协议为例,HTTP/1.1协议定义了一个操作资源的统一接口,主要包括以下内容:

  • 7个HTTP方法:GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS
  • HTTP头信息(可自定义)
  • HTTP响应状态代码(可自定义)
  • 一套标准的内容协商机制
  • 一套标准的缓存机制
  • 一套标准的客户端身份认证机制

REST还要求,对于资源执行的操作,其操作语义必须由HTTP消息体之前的部分完全表达,不能将操作语义封装在HTTP消息体内部。这样做是为了提高交互的可见性,以便于通信链的中间组件实现缓存、安全审计等等功能。

什么是超文本驱动?

“超文本驱动”又名“将超媒体作为应用状态的引擎”(Hypermedia As The Engine Of Application State,来自Fielding博士论文中的一句话,缩写为HATEOAS)。将Web应用看作是一个由很多状态(应用状态)组成的有限状态机。资源之间通过超链接相互关联,超链接既代表资源之间的关系,也代表可执行的状态迁移。在超媒体之中不仅仅包含数据,还包含了状态迁移的语义。以超媒体作为引擎,驱动Web应用的状态迁移。通过超媒体暴露出服务器所提供的资源,服务器提供了哪些资源是在运行时通过解析超媒体发现的,而不是事先定义的。从面向服务的角度看,超媒体定义了服务器所提供服务的协议。客户端应该依赖的是超媒体的状态迁移语义,而不应该对于是否存在某个URI或URI的某种特殊构造方式作出假设。一切都有可能变化,只有超媒体的状态迁移语义能够长期保持稳定。

一旦读者理解了上述REST的五个关键词,就很容易理解REST风格的架构所具有的6个的主要特征:

  • 面向资源(Resource Oriented)
  • 可寻址(Addressability)
  • 连通性(Connectedness)
  • 无状态(Statelessness)
  • 统一接口(Uniform Interface)
  • 超文本驱动(Hypertext Driven)

这6个特征是REST架构设计优秀程度的判断标准。其中,面向资源是REST最明显的特征,即,REST架构设计是以资源抽象为核心展开的。可寻址说的是:每一个资源在Web之上都有自己的地址。连通性说的是:应该尽量避免设计孤立的资源,除了设计资源本身,还需要设计资源之间的关联关系,并且通过超链接将资源关联起来。无状态、统一接口是REST的两种架构约束,超文本驱动是REST的一个关键词,在前面都已经解释过,就不再赘述了。

从架构风格的抽象高度来看,常见的分布式应用架构风格有三种:

  • 分布式对象(Distributed Objects,简称DO)架构实例有CORBA/RMI/EJB/DCOM/.NET Remoting等等
  • 远程过程调用(Remote Procedure Call,简称RPC)架构实例有SOAP/XML-RPC/Hessian/Flash AMF/DWR等等
  • 表述性状态转移(Representational State Transfer,简称REST)

架构实例有HTTP/WebDAV

DO和RPC这两种架构风格在企业应用中非常普遍,而REST则是Web应用的架构风格,它们之间有非常大的差别。

REST与DO的差别在于:

  • REST支持抽象(即建模)的工具是资源,DO支持抽象的工具是对象。在不同的编程语言中,对象的定义有很大差别,所以DO风格的架构通常都是与某种编程语言绑定的。跨语言交互即使能实现,实现起来也会非常复杂。而REST中的资源,则完全中立于开发平台和编程语言,可以使用任何编程语言来实现。
  • DO中没有统一接口的概念。不同的API,接口设计风格可以完全不同。DO也不支持操作语义对于中间组件的可见性。
  • DO中没有使用超文本,响应的内容中只包含对象本身。REST使用了超文本,可以实现更大粒度的交互,交互的效率比DO更高。
  • REST支持数据流和管道,DO不支持数据流和管道。

DO风格通常会带来客户端与服务器端的紧耦合。在三种架构风格之中,DO风格的耦合度是最大的,而REST的风格耦合度是最小的。REST松耦合的源泉来自于统一接口+超文本驱动。

REST与RPC的差别在于:

  • REST支持抽象的工具是资源,RPC支持抽象的工具是过程。REST风格的架构建模是以名词为核心的,RPC风格的架构建模是以动词为核心的。简单类比一下,REST是面向对象编程,RPC则是面向过程编程。
  • RPC中没有统一接口的概念。不同的API,接口设计风格可以完全不同。RPC也不支持操作语义对于中间组件的可见性。
  • RPC中没有使用超文本,响应的内容中只包含消息本身。REST使用了超文本,可以实现更大粒度的交互,交互的效率比RPC更高。
  • REST支持数据流和管道,RPC不支持数据流和管道。
  • 因为使用了平台中立的消息,RPC风格的耦合度比DO风格要小一些,但是RPC风格也常常会带来客户端与服务器端的紧耦合。支持统一接口+超文本驱动的REST风格,可以达到最小的耦合度。

比较了三种架构风格之间的差别之后,从面向实用的角度来看,REST架构风格可以为Web开发者带来三方面的利益:

  • 简单性
    采用REST架构风格,对于开发、测试、运维人员来说,都会更简单。可以充分利用大量HTTP服务器端和客户端开发库、Web功能测试/性能测试工具、HTTP缓存、HTTP代理服务器、防火墙。这些开发库和基础设施早已成为了日常用品,不需要什么火箭科技(例如神奇昂贵的应用服务器、中间件)就能解决大多数可伸缩性方面的问题。
  • 可伸缩性
    充分利用好通信链各个位置的HTTP缓存组件,可以带来更好的可伸缩性。其实很多时候,在Web前端做性能优化,产生的效果不亚于仅仅在服务器端做性能优化,但是HTTP协议层面的缓存常常被一些资深的架构师完全忽略掉。
  • 松耦合
    统一接口+超文本驱动,带来了最大限度的松耦合。允许服务器端和客户端程序在很大范围内,相对独立地进化。对于设计面向企业内网的API来说,松耦合并不是一个很重要的设计关注点。但是对于设计面向互联网的API来说,松耦合变成了一个必选项,不仅在设计时应该关注,而且应该放在最优先位置。

有的读者可能会问:“你说了这么多,REST难道就没有任何缺点了吗?”当然不是,正如Fielding在博士论文中阐述的那样,评价一种软件架构的优劣,不能脱离开软件的具体运行环境。永远不存在适用于任何运行环境的、包治百病的银弹式架构。笔者在前面强调过REST是一种为运行在互联网环境中的Web应用量身定制的架构风格。REST在互联网这个运行环境之中已经占据了统治地位,然而,在企业内网运行环境之中,REST还会面临DO、RPC的巨大挑战。特别是一些对实时性要求很高的应用,REST的表现不如DO和RPC。所以需要针对具体的运行环境来具体问题具体分析。但是,REST可以带来的上述三方面的利益即使在开发企业应用时,仍然是非常有价值的。所以REST在企业应用开发,特别是在SOA架构的开发中,已经得到了越来越大的重视。本专栏将有一篇文章专门介绍REST在企业级应用中与SOA的结合。

到了这里,“REST究竟是什么”这个问题笔者就解答完了。本文开头那些说法是否正确,笔者还是笑而不语,读者此时应该已经有了自己的判断。在接下来的REST系列文章中,我将会为读者澄清一些关于HTTP协议和REST的常见误解。

文章目录
  1. 1. REST架构风格架构约束
  2. 2. REST详解
    1. 2.1. 什么是资源?
    2. 2.2. 什么是资源的表述?
    3. 2.3. 什么是状态转移?
    4. 2.4. 什么是统一接口?
    5. 2.5. 什么是超文本驱动?
|