REST(Representational State Transfer) 是Roy Thoms Fielding在其博士论文中所提出的一种架构风格(Architectual Style)。
http://roy.gbiv.com/pubs/dissertation/top.htm
http://www.redsaga.com/opendoc/REST_cn.pdf 可以说它也体现了整个互联网架构的基本设计原则。随着AJAX等技术的发展,互联网的资源语义逐渐得以恢复,最近对于REST的讨论也热烈起来。
http://www.ibm.com/developerworks/cn/web/wa-ajaxarch/
在Fielding的论文中对REST有如下陈述:
The name “Representational State Transfer” is intended to evoke an image of how a well-designed
Web application behaves: a network of web pages (a virtual state-machine), where the
user progresses through the application by selecting links (state transitions), resulting in
the next page (representing the next state of the application) being transferred to the user
and rendered for their use.
点击超链接之后,服务器端返回资源的某种表示(Resource Representation), 客户端的状态(Representational State)随之发生迁移(transition),在服务器端返回的表示中存在着到其他状态的迁移链接,使得我们始终自动具有进一步迁移的能力(这和 ajax中所谓返回纯粹数据其实是不同的). 这种图景其实也正是Tim Berners-Lee最早所设想的web的图景。因为REST是对互联网架构设计的一种抽象,因此所谓的Restful其实就是尽量符合现有Web标 准。从概念上说,REST所关注的主要还是分布式资源信息交换,而不是对复杂的业务逻辑进行抽象。遵循REST将会使整个互联网受益,确保路由器,缓存, 代理,浏览器,服务器等各个组件可以协同工作,它的意义并不是针对单个应用程序的。不过与witrix体系架构相对比,我们还是可以发现REST架构风格 对于一般web程序的参考价值。
1. 通过唯一的,确定的url来标定可访问的资源。url定义了后台资源的访问界面,明确区分了浏览器和服务器两个分离的状态空间。这种两分的架构约束是 witrix平台最重要的设计原则。在witrix平台中,Jsplet, BizFlow, PageFlow,AuthMap等技术完全体现在url的精化设计上,系统中所涉及到的所有关键概念都对应于url中的明确组分。而JSF等技术通过对 象封装模糊了资源的访问界面,迫使我们只能通过一个错综复杂的对象包络来理解系统的交互过程。
2. REST强调整个交互图景中所有需要的相关信息都是in band的,而且语义上不同的部分都对应于特定的语法上不同的部分。例如为了保证url的不透明性和稳定性,一些信息通过http协议的header来传 递。这里强调的语义自明性实际上是脱离具体知识体系的形式上的可区分性。在现有的服务器端程序中, 因为直接接触到的是已经解析好的parameter集合, 因此Witrix平台中关注的是在参数集合中识别出特定的形式结构, 这通过EngineURL对象实现.
3. HTTP中明确区分了GET/POST/PUT/DELETE四种标准操作, 并对它们的语义进行了精确的限定. 而所谓的RPC(Remote Procedure Call)与此是不同的. RPC上承载的方法数可以是无限多的,但是这种无限多的操作反而从某种层面上说是简单的,是对称的,没有可区分性。而在REST中,在确定资源这一限制 下,我们可以区分出GET/POST/DELETE/PUT这四种有限但是不同的语义。 是否这四种语义构成完备的操作空间?从某种意义上说, 这四种操作覆盖了资源的整个生命周期, 它自然满足了某种完备性. 但是抽象意义上的完备性并不意味着它在物理层面上也是完备的. 我们都知道二维空间是完备的,但是二维描述并不是三维空间的合适表达. 在Witrix体系下,WebAction所提供的完备的操作集合包括Query, ViewDetail, Update, Add和BizAction.
BizAction是个特定的扩展,所有不便于直接归类到CRUD操作的操作都可以归类到这一Action的名 义下. Witrix架构中把CRUD看作是一个更大的Action空间的一个子空间, 对此子空间的结构进行了细致的划分, 所关注的重点是对部分信息的更明确的表达, 而不是对程序整体的建模.
区分GET/POST/PUT/DELETE四种操作, 最重要的意义在于定义了GET和其他操作的区别. http://www.w3.org/DesignIssues/Axioms.html
a. in HTTP, GET must not have side effects
b. in HTTP, anything which does not have side-effects should use GET
在GET这种语义下, 才可能建立独立的cache组件, 而正是因为cache的存在, 才使得web成为infomation space而不是computing program. 而在Witrix平台中, 很多通用机制的建立(例如精确到数据行的访问权限)都需要对于CRUD做出精细的区分, 而不仅仅是识别出GET操作.
4. REST中虽然定义了具有概念稳定性的url, 但是因为操作集合有限,而且强调服务器端的无状态性, 因此一般认为这种结构并不是面向对象的. 不过,在我看来,面向对象首先意味着一组相关性的聚集, 实际上从语义层面上看, REST与witrix平台的jsplet框架非常接近, 最大的差别在于服务器端明确定义的thisObj---this指针. 服务器端的无状态性对于网站应用而言是必要的, 但是对于复杂的企业应用而言并不是合适的约束.
5. 对整个互联网应用而言,URI应该是不透明的,它的结构对互联网中间应用而言应该是不暴露的. 资源的结构是与整个互联网架构无关的. 最近业内鼓吹REST的时候往往也推崇所谓beautify的url, 例如 http://www.my.com/blog/3/comment/1. 这种结构不过是维护url稳定性的一种副产品, 在我看来, 它对于REST而言并不是必需的. 不过根据这些年关系数据库应用积累的经验,识别集合和集合中的个体是一种非常通用的场景,因此我们可能规范化这种结构,甚至搜索引擎等外部组件也可能理解 这种语义,从而实现更加复杂的语义网络。在现有的所谓支持REST的web框架中, 往往支持这种规范化的url直接映射到后台的响应函数上. https://cetia4.dev.java.net/files/documents/5545/38989/cetia4_tutorial.pdf. 例如在cetia4框架中, GET /blog/3将会被映射到后台函数 String render(RenderContext context, int id)函数上. 在witrix平台中, 缺省并不采用beautify的url, 但是因为对于语法成分具有明确的定义, objectEvent=ViewDetail&id=3这样的url将映射到后台biz-flow中的action段.
<action id="ViewDetail-default"><source></source>
</action>
在action 中我们直接接触到的不是id值,而是id值相对应的实体对象本身. 对于objectEvent=Remove, 我们可能一次删除多条记录, 则在后台bizflow中action=Remove-default段将会被调用多次,每次处理一个实体. 这些自动处理机制都离不开对于标准化url组分的明确理解.
在网站应用中, 我们一般也通过url rewrite机制来支持简化的层级url. 但是这种根据位置来确定语义成分的url格式其实也存在着很大的局限性, 在cetia4的映射中很多时候都会出现含混的情况. 而且因为资源是抽象的, 页面中的相对路径计算会出现一定的困难. 在witrix平台中, 通过tpl模板语言的标签增强机制, 我们重新定义了页面中的相对路径计算规则, 从而大大简化了资源管理问题. 在tpl中相对路径计算永远是基于当前模板文件的, 例如对于通过<c:include src="subdir/included.tpl">引入的子页面included.tpl, 在其中的 <script src="included.js" type="text/javascript"></script> 等使用相对路径的语句会在编译期被转换为使用绝对路径, 生成 <script src="/contextPath/root/subdir/included.js" type="text/javascript"></script> 等语句.
6. 一旦url格式被规范化, 我们就可以基于它在应用程序中发展很多全局结构. 例如在cetia4中, 可以建立全局的navigation模型, 并提供了一个breadcrumb 导航栏. 这是一种全局的链接管理机制,在一定程度上实现了导航信息压缩. 但是因为其没有对象结构支撑, 与Witrix平台的PageFlow技术相比, cetia4的方式不过是非常原始的一级策略, 它对于对象生命周期的管理也是过于简陋的.http://canonical.iteye.com/blog/32552
7. REST中强调generic interface 而不是强调custom interface. 实际上目前业内的对象化方案很多时候都沉迷于提供特定结构的构造方法, 很多面向对象框架本身就在构造各式各样的特定结构。一种通用的结构只存在于概念中,是复杂结构背后的事情。但是在很多情况下, generic interface无论在实现成本还是概念成本上都是更加低廉的. 在witrix平台中, jsplet框架所实现的对象化就是一种generic方式的,弱类型化的, 而不是强类型的对象结构的。
8. 关于REST的另一个有趣的问题是如果大量使用HTTP内置特性,是否我们的应用将严格绑定到http协议上,不再是所谓的protocol independence。不过我们真的需要同一语义模型的不同实现吗.</c:include>
在Fielding的论文中对REST有如下陈述:
The name “Representational State Transfer” is intended to evoke an image of how a well-designed
Web application behaves: a network of web pages (a virtual state-machine), where the
user progresses through the application by selecting links (state transitions), resulting in
the next page (representing the next state of the application) being transferred to the user
and rendered for their use.
点击超链接之后,服务器端返回资源的某种表示(Resource Representation), 客户端的状态(Representational State)随之发生迁移(transition),在服务器端返回的表示中存在着到其他状态的迁移链接,使得我们始终自动具有进一步迁移的能力(这和 ajax中所谓返回纯粹数据其实是不同的). 这种图景其实也正是Tim Berners-Lee最早所设想的web的图景。因为REST是对互联网架构设计的一种抽象,因此所谓的Restful其实就是尽量符合现有Web标 准。从概念上说,REST所关注的主要还是分布式资源信息交换,而不是对复杂的业务逻辑进行抽象。遵循REST将会使整个互联网受益,确保路由器,缓存, 代理,浏览器,服务器等各个组件可以协同工作,它的意义并不是针对单个应用程序的。不过与witrix体系架构相对比,我们还是可以发现REST架构风格 对于一般web程序的参考价值。
1. 通过唯一的,确定的url来标定可访问的资源。url定义了后台资源的访问界面,明确区分了浏览器和服务器两个分离的状态空间。这种两分的架构约束是 witrix平台最重要的设计原则。在witrix平台中,Jsplet, BizFlow, PageFlow,AuthMap等技术完全体现在url的精化设计上,系统中所涉及到的所有关键概念都对应于url中的明确组分。而JSF等技术通过对 象封装模糊了资源的访问界面,迫使我们只能通过一个错综复杂的对象包络来理解系统的交互过程。
2. REST强调整个交互图景中所有需要的相关信息都是in band的,而且语义上不同的部分都对应于特定的语法上不同的部分。例如为了保证url的不透明性和稳定性,一些信息通过http协议的header来传 递。这里强调的语义自明性实际上是脱离具体知识体系的形式上的可区分性。在现有的服务器端程序中, 因为直接接触到的是已经解析好的parameter集合, 因此Witrix平台中关注的是在参数集合中识别出特定的形式结构, 这通过EngineURL对象实现.
3. HTTP中明确区分了GET/POST/PUT/DELETE四种标准操作, 并对它们的语义进行了精确的限定. 而所谓的RPC(Remote Procedure Call)与此是不同的. RPC上承载的方法数可以是无限多的,但是这种无限多的操作反而从某种层面上说是简单的,是对称的,没有可区分性。而在REST中,在确定资源这一限制 下,我们可以区分出GET/POST/DELETE/PUT这四种有限但是不同的语义。 是否这四种语义构成完备的操作空间?从某种意义上说, 这四种操作覆盖了资源的整个生命周期, 它自然满足了某种完备性. 但是抽象意义上的完备性并不意味着它在物理层面上也是完备的. 我们都知道二维空间是完备的,但是二维描述并不是三维空间的合适表达. 在Witrix体系下,WebAction所提供的完备的操作集合包括Query, ViewDetail, Update, Add和BizAction.
BizAction是个特定的扩展,所有不便于直接归类到CRUD操作的操作都可以归类到这一Action的名 义下. Witrix架构中把CRUD看作是一个更大的Action空间的一个子空间, 对此子空间的结构进行了细致的划分, 所关注的重点是对部分信息的更明确的表达, 而不是对程序整体的建模.
区分GET/POST/PUT/DELETE四种操作, 最重要的意义在于定义了GET和其他操作的区别. http://www.w3.org/DesignIssues/Axioms.html
a. in HTTP, GET must not have side effects
b. in HTTP, anything which does not have side-effects should use GET
在GET这种语义下, 才可能建立独立的cache组件, 而正是因为cache的存在, 才使得web成为infomation space而不是computing program. 而在Witrix平台中, 很多通用机制的建立(例如精确到数据行的访问权限)都需要对于CRUD做出精细的区分, 而不仅仅是识别出GET操作.
4. REST中虽然定义了具有概念稳定性的url, 但是因为操作集合有限,而且强调服务器端的无状态性, 因此一般认为这种结构并不是面向对象的. 不过,在我看来,面向对象首先意味着一组相关性的聚集, 实际上从语义层面上看, REST与witrix平台的jsplet框架非常接近, 最大的差别在于服务器端明确定义的thisObj---this指针. 服务器端的无状态性对于网站应用而言是必要的, 但是对于复杂的企业应用而言并不是合适的约束.
5. 对整个互联网应用而言,URI应该是不透明的,它的结构对互联网中间应用而言应该是不暴露的. 资源的结构是与整个互联网架构无关的. 最近业内鼓吹REST的时候往往也推崇所谓beautify的url, 例如 http://www.my.com/blog/3/comment/1. 这种结构不过是维护url稳定性的一种副产品, 在我看来, 它对于REST而言并不是必需的. 不过根据这些年关系数据库应用积累的经验,识别集合和集合中的个体是一种非常通用的场景,因此我们可能规范化这种结构,甚至搜索引擎等外部组件也可能理解 这种语义,从而实现更加复杂的语义网络。在现有的所谓支持REST的web框架中, 往往支持这种规范化的url直接映射到后台的响应函数上. https://cetia4.dev.java.net/files/documents/5545/38989/cetia4_tutorial.pdf. 例如在cetia4框架中, GET /blog/3将会被映射到后台函数 String render(RenderContext context, int id)函数上. 在witrix平台中, 缺省并不采用beautify的url, 但是因为对于语法成分具有明确的定义, objectEvent=ViewDetail&id=3这样的url将映射到后台biz-flow中的action段.
<action id="ViewDetail-default"><source></source>
xml 代码
- <action id="ViewDetail-default">
- <source>
- 在这里直接拿到entity对象,而不是id值
- </source>
- </action>
在action 中我们直接接触到的不是id值,而是id值相对应的实体对象本身. 对于objectEvent=Remove, 我们可能一次删除多条记录, 则在后台bizflow中action=Remove-default段将会被调用多次,每次处理一个实体. 这些自动处理机制都离不开对于标准化url组分的明确理解.
在网站应用中, 我们一般也通过url rewrite机制来支持简化的层级url. 但是这种根据位置来确定语义成分的url格式其实也存在着很大的局限性, 在cetia4的映射中很多时候都会出现含混的情况. 而且因为资源是抽象的, 页面中的相对路径计算会出现一定的困难. 在witrix平台中, 通过tpl模板语言的标签增强机制, 我们重新定义了页面中的相对路径计算规则, 从而大大简化了资源管理问题. 在tpl中相对路径计算永远是基于当前模板文件的, 例如对于通过<c:include src="subdir/included.tpl">引入的子页面included.tpl, 在其中的 <script src="included.js" type="text/javascript"></script> 等使用相对路径的语句会在编译期被转换为使用绝对路径, 生成 <script src="/contextPath/root/subdir/included.js" type="text/javascript"></script> 等语句.
6. 一旦url格式被规范化, 我们就可以基于它在应用程序中发展很多全局结构. 例如在cetia4中, 可以建立全局的navigation模型, 并提供了一个breadcrumb 导航栏. 这是一种全局的链接管理机制,在一定程度上实现了导航信息压缩. 但是因为其没有对象结构支撑, 与Witrix平台的PageFlow技术相比, cetia4的方式不过是非常原始的一级策略, 它对于对象生命周期的管理也是过于简陋的.http://canonical.iteye.com/blog/32552
7. REST中强调generic interface 而不是强调custom interface. 实际上目前业内的对象化方案很多时候都沉迷于提供特定结构的构造方法, 很多面向对象框架本身就在构造各式各样的特定结构。一种通用的结构只存在于概念中,是复杂结构背后的事情。但是在很多情况下, generic interface无论在实现成本还是概念成本上都是更加低廉的. 在witrix平台中, jsplet框架所实现的对象化就是一种generic方式的,弱类型化的, 而不是强类型的对象结构的。
8. 关于REST的另一个有趣的问题是如果大量使用HTTP内置特性,是否我们的应用将严格绑定到http协议上,不再是所谓的protocol independence。不过我们真的需要同一语义模型的不同实现吗.</c:include>