REST真相

REST不是CRUD, 本站已经进行大量讨论(见标签REST架构),那么REST到底是什么?

最严重的误解就是,将REST的POST, GET, PUT, DELETE和数据库资源的增删改查CRUD联系起来, POST, GET, PUT, DELETE = Create, Read, Update, Delete,这是相当多REST框架的错误导向。

从REST名词中,我们就看到状态的转移,也就是说,以URI为标志、以超文本或超媒体驱动(hypertext/Hypermedia)的状态转移是REST架构核心。真正REST API使用场景如下图。

1.一个简单的get就应该获得REST框架的入口点entry point,类似Atom Publishing Protocol的Discovery。如图中,返回的是一个Service列表,有的REST框架案例是在Service之前再做一个Action类,作为REST入口,其实没必要这么画蛇添足,直接将Service暴露给REST客户端,这才有SOA架势。

2.REST客户端会根据终端用户事件请求,定位某个Service,如果用户请求的是FooService,那么找到其入口点是/well=known-url/foo

3.客户端通过向/well=known-url/foo发出GET命令,获得FooService的列表List,如图中XML的fooitems,其中也包括下一步状态切换可能的URI:REVERSE,如果熟悉GOF设计模式的状态模式,就会非常自然理解这点。REST其实是把事件和状态分离到客户端和服务器两个部分。

4.如果终端用户发生请求事件,触发了状态转换,那么就激活fooitems中的REVERSE URI:/well=known-url/foo/1/reverse

5.注意了,这是区别于CRUD关键一步,这时客户端将向选择的下一个状态REVERSE URI发出PUT命令,服务器后端业务组件接受PUT命令后,将改变资源的状态。资源状态改变后返回一个操作结果。

6.客户端再次发出GET命令,获得当前服务器资源的状态。

CRUD vs. Hypermedia:
http://hinchcliffe.org/archive/2009/08/06/17119.aspx

Your Web Service Might Not Be RESTful If
你的Web服务也许不是RESTful
http://theamazingrando.com/blog/?p=107

RESTful架构深入分析
http://www.jdon.com/jivejdon/thread/36716.html

[该贴被banq于2009-08-07 11:32修改过]
[该贴被banq于2009-08-07 11:38修改过]


问几个问题:
1、在上例中的状态转移,是不是指的
(1)空状态转移到服务列表状态
(2)服务列表状态转移到具体服务描述状态
(3)具体服务描述状态转移到操作结果状态
(4)操作结果状态转移到资源列表状态

2、这和传统的web模式有啥区别
(1)BookAction?method=getServices,返回包含所有services的HTML代码(相当于上文的xml),其中每个services是一个连接(相当于上文的URI)。
  (2)BookAction?method=servicesInfo&id=1,点击uri返回Service的信息HTML代码,包含提交请求的连接(相当于URI)
(3)附加提交信息调用BookAction?method=callservice&id=1,得到返回结果

我发现用传统struts就匹配上图模式,而且每一种资源都能匹配唯一uri,BookAction?method=getServices、BookAction?method=servicesInfo&id=1、BookAction?method=callservice&id=1,我的漏洞在哪?

BookAction?method=getServices是RPC,你调用参数中有服务的名称,而REST中如果要getService的话,调用/well=known-url/foo就可以了。

两者区别:
1. 可伸缩性,负载平衡,可以任意指定一个服务器上的服务,而且是由服务器这里指定的URI,可见我的"REST架构本质"一文。

2.调用/well=known-url/foo,客户端就不和具体服务名称耦合。

目前只想到这两点。

>而且是由服务器这里指定的URI

我是不是可以这样理解,服务器初始化的时候为每个资源分配uri而不是拿服务的名字访问,比如说BookAction?method=getServices,有可能随着程序变更,这个服务不再需要了,但是用uri:/well=known-url/foo作为BookAction?method=getServices服务资源的访问uri,即便以后getServices不需要,也要其他的服务映射到/well=known-url/foo作为这个uri的资源,在这种假设下,产生两个疑问:
1 服务器在初始化的时候要知道全局的所有资源并为其分配uri,这其中是否涉及某种配置或者注册机制,而且依赖于分析人员前期对于资源的状态的准确定义
2 假如一张图片寸在于web项目的images目录下,为其分配uri为/well=known-url/images/1,但是开发人员应该用/well=known-url/images/1访问,却用http://localhost:8080/images/1.jpg访问,则这种非标准uri方式访问资源导致表述无法延续到下一个状态,将会导致致命错误。

>服务器初始化的时候为每个资源分配uri而不是拿服务的名字访问
可以这么理解。

其实SPring有个Web Flow,如果把它转移到客户端执行,就很有RESTful了。比如Web Flow中有:
<webflow id="LoginSequence" start-state="loginForm">

<action-state id="loginForm">
<action bean="loginFormAction"/>
<transition on="success" to="formView"/>
</action-state>
...
<view-state id="formView" view="enterCredentials">
<transition on="submit" to="bindAndValidateForm"/>
</view-state>
...
<end-state id="successView" view="displayMain"/>

还有工作流,都可以用REST来统一他们。

在REST里面,最为重要的一个约束是“通用接口”,Roy说HTTP的最常用的方式是作为其他协议的载体,比如xxx over http,然而这是一种误用,http正确用法应该是将使用者的动作映射到某个事物上。
以上图为例:
<services>
<service>
<name>xxx</name>
<uri>xxx</uri>
</service>
</services>
这个写法仍旧需要服务器和客户端维护统一的语义,比如客户端怎么知道从<service>标签中取name,而不是从<job>标签中取,本质上还是xxx over http,如何体现通用接口含义,换句话说如果动态扩展在服务器端和客户端增加缓存服务器(分层约束),那么缓存服务器需要知道去<name>标签中找缓存判断条件而不是其他的,仍旧需要在服务器,客户端和缓存三者之间维护语义的一致性,这又如何体现通用接口?

>Roy说HTTP的最常用的方式是作为其他协议的载体 http正确用法应该是将使用者的动作映射到某个事物上
给个Roy原文,我先看看理解一下。

这个统一接口可以使用例如Atom publish Protocol,格式如下:

<service xmlns="http://purl.org/atom/app#"
xmlns:atom="http://www.w3.org/2005/Atom">
<workspace>
<atom:title>Service</atom:title>
<collection href="REPLACE" >
<atom:title>Entries</atom:title>
<categories>
<atom:category
term="storage" scheme="urn:storage" label="storage"/>
</categories>
</collection>
</workspace>
</service>

[该贴被banq于2009-08-07 18:14修改过]

还是不明白你的真相是指什么?REST是状态的转移?

怎么样在我的记忆中,REST是讲资源(或服务)的定义及划分。
对数据的操作,最终都有要归为4类:CRUD,因而对外暴露的服务也归到4种。带来的便利有:

1) 事务的处理和定义
2) 权限的设定
3) Cache的设定
4) 框架设计上的统一管理

等等等

REST是否真的能够承载起希望达到的作用还有待考证,我感觉REST可能会有以下2点问题:
1、REST每次都需要将客户端的状态发送给服务器,那么客户端的安全如何保证?可以说信息越多,出现泄露的可能就越大,黑客就越可以知道用户详尽的信息。
2、REST的服务器的一些访问权限需要通过服务器的防火墙设置(比如限定PUT,或者GET)这样其实就将问题分散到多个地方,非常不利于管理。更主要的将成为推广的一大阻碍。

个人感觉soa 和 restful 在思想上是一样的。
一个是service based,一个是resource based。
而我觉得 service 就是 resource。

所以他们是一样一样的。就像webservice和ejb是一样的一样。

-----请指教。