架构模式之REST架构

  直至今日,分布式系统(Distributed System)已经取得了大规模的应用,特别是Web的发展,已经给软件开发带来了翻天覆地的变化,这一点已经毋庸置疑了。程序员

  构建分布式系统经常使用的技术一般就是使用分布式对象(DO),远程过程调用(RPC)方式。Web的架构为构建分布式系统带来了全新的开发方式,它抛弃了大量重量级、专家级的中间件,采用各类简单的中间件来知足企业级的需求,例如可靠性,安全,事务等。
 
REST架构
  Web的基础架构就是REST架构,虽然Web开发从HTTP诞生那天起就应该是REST方式的,可是几乎全部当时的开发者都是使用传统的DO或者RPC去开发Web这个特殊的分布式系统。
  REST是英文Representational State Transfer的缩写,中文翻译为“表述性状态转移”。它是由Roy Thomas Fielding博士在2000年首次提出的。在这篇论文中,博士为咱们描绘了开发基于互联网的网络软件的蓝图。因为这篇论文学术性太强,致使它并未引发程序员们的注意。直到ROR(Ruby On Rails) 风行起来,它所宣扬的REST架构才真正的为人们所熟悉。可是ROR所提倡的只不过是使用HTTP协议完成简单的CRUD操做,离真正的REST架构还有很长一段路要走。在2008年的某次大会(不记得了)上,Fielding博士终于提出了真正的REST架构的核心思想: REST架构就是使用超媒体做为应用状态引擎(HATEOAS,即hypermedia as the engine of application state)
 
REST核心
   REST架构的核心理念就是使用HTTP做为应用协议操做网络资源,而且以超媒体(hypermedia)做为应用状态转移的载体。这里有如下几个重要的概念:
1. 资源
  任何能够在网络上访问的数据都是资源,为了让其余的系统能访问这些资源,能够采用统一资源标识符(URI)来标识每个资源。在Web开发中,最为经常使用的一种URI就是URL了。对于资源来讲,因为每一个系统对它的描述格式是不一样的,这就致使同一个资源可能使用不一样的表述方式,好比JSON格式,XML格式的。在REST架构中,资源的URL中通常不区分每种格式,格式交由Http Header去处理,好比application/json。
2. HTTP协议
  REST架构使用HTTP做为应用协议去访问Web上的资源,而不是像传统的Web Service同样只是把HTTP当作一种传输协议。把HTTP当作应用协议体现为充分利用HTTP协议的消息来描述应用业务,体现为如下几点:
第一点,利用HTTP的Verb动词去描述应用的业务逻辑。好比:
GET 请求获取Request-URI所标识的资源,用于获取业务数据。
POST 在Request-URI所标识的资源后附加新的数据,用于建立业务数据。
PUT 请求服务器存储一个资源,并用Request-URI做为其标识,用于更新业务数据。
PATCH 若是说PUT是更新整个资源的话,PATCH能够只更新资源的一部分。
DELETE 请求服务器删除Request-URI所标识的资源,用于删除业务数据。
这几个是经常使用的完成CRUD操做的动词。其余的还有像:
HEAD 请求获取由Request-URI所标识的资源的响应消息报头。
TRACE 请求服务器回送收到的请求信息,主要用于测试或诊断。
CONNECT 保留未来使用。
OPTIONS 请求查询服务器的性能,或者查询与资源相关的选项和需求。

  具体的一个例子是,在业务逻辑中,咱们有一个功能是获取一个员工的信息,在实现这个分布式应用的时候,咱们就使用GET方法去访问指定的URI来申请员工的信息。这就是使用HTTP的动词去描述应用的业务。数据库

第二点,使用HTTP的状态响应代码来描述业务逻辑的执行结果
  这一点不用多说,好比200来表示获取资源成功,201来表示资源建立成功,资源更新成功,404表示没有找到请求的资源,500表示服务器内部出错。
第三点,使用HTTP消息头的其余一些内容来辅助描述业务的数据和状态
  好比使用消息头中表示消息体类型的Content-Type,用于表示传输的数据新旧的Etag和Last-Modified,用于更新数据配合Etag使用的If-Match,用于缓存的Cache-Control,用于受权的Authorization等。
第四点,使用HTTP消息体中的超媒体表示应用程序的状态
  在老式的Web开发中,你们都使用URL隧道技术(来源于REST in Practice一书的称呼),其实就是把业务数据嵌入在了URL中,当作查询字符串处理,这在REST架构中是不能接受的。 严格的REST架构认为REST架构的先决条件就是使用超媒体做为应用程序的状态引擎。按个人理解,就是消息体存放的内容就是超媒体,它们描述了业务的当前状态和接下来可能的状态,根据这些描述,客户端就知道了业务接下来可能的操做。
  好比在电子商务网站中,若是客户下了一个订单的话,客户会使用POST去建立一个订单,这个时候消息体包含的就是订单的一些数据,当服务端收到这个Request后,会在后端数据库中建立订单信息,而后会在Response的消息体中返回建立的订单的信息并包含接下来客户能够作的步骤,这些步骤一般就是一些超连接,好比使用GET获取订单的最新状态,使用DELETE删除该订单,或者使用POST建立付费申请资源等等。
3. 超媒体
  其实超媒体并非什么神秘的概念,超媒体只是超级媒体的缩写。超媒体是一种采用非线性网状结构对块状多媒体信息(包括文本、图像、视频等)进行组织和管理的技术。 超媒体在本质上和超文本是同样的,只不过超文本技术在诞生的初期管理的对象是纯文本,因此叫作超文本。随着多媒体技术的兴起和发展,超文本技术的管理对象从纯文本扩展到多媒体,为强调管理对象的变化,就产生了超媒体这个词。
  链接各类媒体的形式就是超连接,因此超连接是超媒体的核心元素。在REST架构中,这个思路一样成立,消息体中的超媒体,核心的元素也就是超连接,各类形式表示的超连接;这些超连接能够被客户端很容易的就能解析,好比一般可使用XHTML做为超媒体载体,由于XHTML有超连接元素,也可使用Atom做为超媒体载体,由于Atom也有link元素。
  使用超媒体后,程序的业务逻辑再也不像是Web Service开发同样,是由WSDL描述的接口去限定了,而是所有由超媒体(超连接)去驱动。这样当Service作出一些修改后,只会反映到相应的连接中,不须要客户端作出任何的硬性修改(好比Web Service开发中接口的修改)。
 
REST成熟度模型
  REST架构兴起之后,你们就须要给这些凌乱的认为实现了REST思想的网站评定是否知足REST的架构风格。认同比较多的就是Richardson的成熟度模型,Martin Fowler大师也这么谈论,以下图所示:
第0级(level 0)
  这个级别的实现一般只有一个URI入口。应用程序也只是把HTTP做为一种普通的传输协议,在这之上构建应用层的协议实现远程Service的调用,这和CORBA,SOAP,POX(Plain Old XML)调用没有太多分别。
第1级(level 1)
  这个级别的实现使用了大量的URI来描述各类不一样的资源(Resource),同时把复杂的Service的分解为多个资源。可是实现应用的时候只使用单个的HTTP动词(一般是GET或POST)来完成全部的业务逻辑,业务逻辑的行进方向彻底隐藏在URI中(查询字符串中的参数),大多数现行的网站都属于这个级别。
第2级(level 2)
  在第一级的基础之上,这个级别引入HTTP标准的动词词汇,用于增强客户端和资源URI的交互的语义性。好比使用POST/GET/PUT/DELETE完成常见的CRUD操做。在使用标准语义操做词汇的同时,还运用HTTP的标准的CODE代码来表达交互操做的结果。例如200/201/400等表达不一样的交互操做结果。一些设计良好的网站属于这个级别,好比亚马逊S3服务,基于ROR建立的许多服务。
第3级(level 3)
  在第二级的基础之上,这个级别增强了状态转换的表达,增强了状态切换的可发现性。这个级别实现了HATEOAS(Hypertext As The Engine of Application State)的机制,在每个服务器端返回给客户端的消息体中加上一些能够帮助客户端了解和指导可能存在的link,从而按照不一样的link实现不一样的状态的迁移。这就比如给客户端程序就像一个使用浏览器的人同样,资源的Representation就比如展示在浏览器中的HTML同样。浏览的人能够经过HTML中的link实现不一样页面的浏览。经过HATEOAS,准确的来讲只须要对外广告资源的入口,就能够完成全部资源状态之间的切换和导航。
 
Web Service安魂曲?(源于REST in Practice一书的称呼)
  目前来看,答案应该是否认的。我我的以为缘由有下列几点:
  首先,不少开发人员已经熟悉了Web Service的开发方式,即便REST相比而言优点更明显,可是因为不少人比较懒,都倾向于采用成熟的技术,心里通常也抵制新的技术(固然不少人仍是热衷于新技术的),因此Web Service开发还会持续较长一段时间。
  其次,不少Web Service开发人员都是专家级的人物,转向新技术的话其优点将损失殆尽。
  最后,Web Service开发的标准WS-*日趋完善,功能日益强大,并且针对不少的内部平台,WS开发仍然具备强大的吸引力。
  总的来讲,Web Service与REST开发应该不是严格的替代关系,它们会长久的并存并向前发展,就如同REST架构也不会替代MVC开发同样,由于它们都有各自最擅长的场景。
相关文章
相关标签/搜索