全部博文(214)
分类:
2007-12-06 11:08:36
REST英文全称为Representational State Transfer(表述性状态迁移),是2000年Roy Thomas Fielding博士在他的毕业论文中首次提出的概念,国内一帮精英已经把Fielding的论文翻成了中文,但是看完论文还是很难搞清REST到底是什么。
REST是一组设计原则,或说是一种风格,不是架构,Fielding在他的论文中表示符合REST原则的web服务将在可见性、可靠性与可伸缩性等方面获益,而且符合万维网创建的初衷。
Google map()就是REST风格的web服务一例,当光标热点移动时,左下角随之变化的URI可以看出它是根据URI在提供相应的web服务。
REST是一组广义的设计原则,REST本身并没有与Web、HTTP或URI绑定,REST设计原则包括客户-服务器、无状态、缓存、统一接口、分层系统等。既然原则中要求无状态,又何来表述性状态呢?REST原则的无状态指服务器端不保存客户应用状态,连接→请求→响应→断开,客户的上一次请求与下一个请求没有关系(这其实是HTTP的特征)。服务器端响应客户请求返回资源的表述及相关链接(想像一下google返回的页面),该表述的本身就是客户的当前状态,客户按照表述中提供的链接选择下一个表述,迁移到下一个状态。这是我从字面上对REST的解释,也就是服务器通过表述为状态迁移提供指导,而状态的迁移权掌控在用户手里,客户根据自己的需要选择链接,由当前状态迁移到下一个状态。这个解释很肤浅,下面的面向资源架构从根本上对REST作了技术上的诠释。
面向资源架构是一种REST风格的架构,它以资源为研究对象,通过划分资源、定义资源,然后用超媒体将资源串起来,提供客户所需求的服务。面向资源架构包括四个组成元素,具有四个属性。四个组成元素是:资源、资源名、资源表述和链接。四个属性是:可寻址、无状态、连通和统一接口。
(1) 资源
就象面向对象设计取决于问题域对象划分一样,面向资源设计的首要任务就是划分资源,实际上面向资源是极端的面向对象,因为REST中规定了统一接口约束,要求对资源的操作必须是可见的(如HTTP中标准的GET、PUT、DELETE、POST,带暗箱操作的POST不算),因此资源的操作方法是不能自行定义的。
在面向资源设计中的资源可以是任何具有超文本链接价值的东西,资源可以是数据资源,也可以是物理对象,物理对象本身不能在网上传输,但物理对象的元数据可以。当统一接口方法不能满足需求时,可以通过设计资源将操作名词化,例如你“订阅”某个栏目,统一接口中没有“订阅”操作,也不允许你自行定义“订阅”操作,怎么办呢?你可以将“订阅”设计为资源“订阅关系”,“订阅关系”就可以用统一接口中的方法,如GET、PUT、DELETE进行操作了。同样,对于需要异步完成的操作,也可以通过资源将异步操作划分为多个同步操作来完成。总之,资源可以是任何东西,遇到困惑时可以设法通过资源来解决。
(2) 资源名
资源能成为资源的必要条件是:每个资源必须用URI唯一标识。这符合Tim Berners-Lee公理:Web上每一个资源由URL唯一确定。超文本系统、HTTP 和Internet分层协议之间是不能交流的,URI把所有这些协议集成到了web中。资源用URI命名,资源通过URI定位,URI中不仅包含资源的地址,还包含对资源的操作指令,服务器端根据URI中的指令确定客户请求的处理方式。因此,这里的URI不是单纯的网址。
(3) 资源表述
资源是表述的数据源,表述是资源的当前状态(应客户请求返回的网页),对REST风格的服务来说表述是超媒体,表述中不仅包含着当前资源的信息,还包含了相关资源的链接。
因此,表述呈现了资源的当前状态,也链接着资源的其它状态。表述具体涉及资源的数据及数据格式。可用于表述的超媒体格式有多种,如: 应用/XHTML+XML、应用/ATOM+XML、图像/SVG+XML、应用/JSON、应用/WADL+XML。RESTful Web Services》书中对WADL(Web Application Description Language,https://wadl.dev.java.net)较为推崇,WADL是用于描述HTTP资源特征的XML格式定义(词汇表),书中认为WADL剥离了HTTP请求和响应(表述的建造与解析)的细节,支持URI模板及HTTP统一接口,可以特定符合XML Schema定义的XML表述格式,可简化web服务的客户端编程,与其它超媒体格式相比,WADL有其独特的优点。
(4) 资源链接
资源不是孤立的,是可以连通的,资源通过Link或Form链接,Link与Form本身就是资源表述的一种,因此说表述是超媒体。
(1) 可寻址
每个资源由唯一的URI标识,使资源可定位,也因此使缓存成为可能。
(2) 无状态
客户请求与服务响应通过HTTP 通信,HTTP本身是无状态的,HTTP请求在完全封闭的过程中完成,请求中包含了服务器完成请求所必需的全部信息,请求与请求之间没有关联。这样,服务器端无需等待、无需追踪,它只需要关心客户发送请求时的应用状态就足够了。服务器端的服务之间也不需要分工协作,服务扩展只是将服务插入负载均衡器就行了,这样就增强了服务的伸缩性能。
REST 中的无状态是指仅有一种状态,该状态不在服务器端而在客户端。其实,从资源角度来说,服务器端也有状态,那就是资源状态。服务器应客户请求返回资源的表述,资源通过HTTP由资源状态迁移到客户应用状态;客户向服务器上传资源表述(例如Amazon的S3服务),客户应用状态通过HTTP迁移到服务器变成了资源状态,这是不是应该是REST的真正含义?
(3) 连通
资源应该以某种方式连通,也就是资源是链接的,不需要用户在浏览器中键入URI执行跳转。Link或Form链接是资源连通的超媒体。
(4) 统一接口
面向资源架构利用了HTTP的统一接口,HTTP统一接口提供了四种基本操作方法GET、PUT、DELETE和POST,面向资源架构要求所有服务按HTTP标准方式使用GET、PUT、DELETE和POST,这样安全性好,没有副作用产生,其次响应结果具幂等性(数学上术语),即同一请求返回的结果总是相同的(如:任何数不管乘零多少次结果总是零),除非底层资源发生变化。
这是RESTful Web Services》书中一个最简单的例子,因为Web地图是只读的服务。我只是简单总结,以便大家对REST风格的架构有一个直观的认识。
设计步骤如下:
l 分析数据集
l 将数据集划分为资源
对每一个资源
l 用URI给资源定名
l 选择统一接口方法
l 设计客户端→服务器的表述
l 设计服务器→客户端的表述
l 用超媒体链接或表单将资源挂接到现有资源链中
l 正面设想一下该发生什么
l 反面设想一下什么可能发生
(1) 分析数据集
本数据集为各大星球二维平面图,可以通过地理坐标及地名在地图上定位,并展示以点为中心的平面图。
(2) 将数据集划分为资源
资源大体分三类:
l 预定义的一次性资源,如同一个web主页,充当其它资源的顶级入口。你能GET它,但不能DELETE或PUT它。
l 每个对象的资源,每个对象有自己的资源集合,你可以GET、DELETE或PUT对象的资源。
l 经数据处理后获取的资源,例如根据查询条件返回的结果。
本web地图服务资源划分如下:
(1)所有星球列表
(2)某星球上某一个地方(包括整个星球),通过地名识别
(3)某星球上某地理位置,通过经纬度识别
(4)某星球上满足查询条件的地名列表
(5)以某点为中心的某星球地图
这些资源是可以连通的,星球列表中包含每个星球,每个星球包含无数个地方或地理位置,每个地方或地理位置对应以其为中心的地图。
(3) 用URI给资源定名
在面向资源架构中,URI包含了客户请求的所有目标信息,有地址有操作指令。URI是具有语义的。
命名规则如下:
l 继承关系采用路径变量编码,如:/parent/child
l 无继承关系的,用标点符号区分,并列关系用分号,先后关系用逗号,如:/parent/child1;child2,或/parent/child1,child2
l 有处理请求的采用查询变量表示,如:/search?q=earch&start=20
本web地图服务资源命名如下:
资源 |
URI举例 |
(1)所有星球列表 |
|
(2)某星球上某一个地方(包括整个星球),通过地名识别 |
Earth Earth/China/Qingdao |
(3)某星球上某地理位置,通过经纬度识别 |
Earth/36.08,120.35 |
(4)某星球上满足查询条件的地名列表 |
Earth?show=craters+bigger+then+1km Earth/China/Qingdao?show=hotel |
(5)以某点为中心的某星球地图 |
satellite/Earth/36.08,120.35 road/Earth/36.08,120.35 大比例尺图 road.10/Earth/36.08,120.35 小比例尺图 road.1/Earth/36.08,120.35 |
(4) 选择统一接口方法
HTTP提供了四种基本操作方法
l GET:取一个资源的表述
l PUT:创建一个新资源,或修改已有的资源
l DELETE:删除已有资源
l POST:创建已有资源的子资源
本web地图服务是只读的,只需要GET就够了。可以通过HTTP的Last-Modified和Etag,实施条件GET操作。
(5) 设计客户端→服务器的表述(以XHTML为例)
是客户需要填写的表单,如:
Show place,feature,or business:
(6) 设计服务器→客户端的表述(以XHTML为例)
l 所有星球列表
表述呈现了资源的当前状态,也链接着资源的其它状态,但表述并非必须呈现资源的全部状态,可以显示资源的部分状态,同时提供链接,客户可以通过链接转向剩余部分的状态。Google Map在web地图服务中将地图分割成256*256pixels的图块,按客户请求一部分、一部分地显示资源的状态。这里的web地图服务也可以这样。
l 以点为中心的图
(7) 用超媒体链接或表单将资源挂接到现有资源链中
星球--(Link)-→地球--(Form)-→地球上叫青岛的地方--(Link)-→青岛--(Form)-→青岛某酒店位置--(Link)-→丽晶大酒店
(8) 正面设想一下该发生什么
(9) 反面设想一下什么可能发生
如:
l 客户请求的图不存在,响应代码404(Not Found), 或响应代码200(OK)附以一个表述,表述中有相关链接,可能可以找到客户请求的图。
l 客户输入的地名不存在,响应代码404(Not Found),或响应代码303(See Other),附以一组相近的地名供选择
l 客户输入不合理的经纬度,如300,181,响应代码400(Bad Request)
l 服务器问题,返回503(Service Unavailable)或500(Internal Server Error)
REST 风格的面向资源架构基于三个基本的技术:HTTP,URI和XML,但注意它并没有与HTTP绑定,它只是利用了HTTP的统一接口。该架构以资源为中心,服务器端的状态是资源状态,客户端的状态是资源的表述状态,服务器端应客户请求返回资源的表述,资源通过HTTP由资源状态迁移为客户端的表述状态;客户向服务器端上传资源表述,资源由客户端的表述状态通过HTTP迁移为服务器端的资源状态。资源用URI唯一标识、用XML超媒体表述并链接,由 HTTP统一接口执行资源操作。这样使得REST风格的面向资源web服务是可见的、可靠的、可伸缩的。