posts - 262,  comments - 221,  trackbacks - 0

InfoQ上有一篇《深入浅出REST》的文章:http://www.infoq.com/cn/articles/rest-introduction

文章中的主要观点包括了:

 A. 为所有“事物”定义ID
 B. 将所有事物链接在一起
 C. 使用标准方法
 D. 资源多重表述
 E. 无状态通信

读完后有下列疑问:

A. 观点1中这个“ID”如何定义?

文章中提到了使用URI作为所有“事物(资源)” 的唯一ID,于是为了这样一个疑问:为什么不能用URL,而用URI呢?网上对URI和URL的区别并没有一个明确的说服,我个人的理解是这样的:

URI是资源标识符,而URL是资源定位器。假设我们对所有的资源都进行统一标识(注意是全局唯一标识),有一个资源的标记是4321,那么这个4321是URI。而如何获取到这个4321资源呢?URI并没有说明。于是我们可以同HTTP协议,或者FTP协议来获取,这种依赖于特定通讯协议的获取方式就是URL了。

但是不管是URI还是URL,只要指向同一个资源,最终都是通过唯一的这个标识(URI)来区分资源的。

不知道这个理解是否正确?

B. 要为那些“事物”定义ID?

文章中提到了我们不单为一个单一的资源定义ID,我们也可以为资源的集合定义ID。于是就有了这样的疑问:

对于一些集合范围比较明确的资源,比如blog的按年月日分类,我们可以简单地使用诸如这样的URL:http://xxx.com/archive/2010/06/24/324348.html 来表示REST风格的资源,但是如果这个集合的范围是模糊的,或者是靠某些条件表达式的执行结果来限制的,比如说所有符合条件1的文章集合。那么对于这种模式的资源,REST又如何来表示呢?

进一步地引申到实现问题?假如为这么多事物引入ID,那么会不会导致我们的存储结构暴增?在上面这篇文章中也提到了这样的观点:

例如,一个定单资源可以由定单项、地址以及许多其它方面(可能不希望作为单独标识的资源暴露出来)组成。标识所有值得标识的事物,领会这个观念可以进一步引导你创造出在传统的应用程序设计中不常见的资源:一个流程或者流程步骤、一次销售、一次谈判、一份报价请求——这都是应该被标识的事物的示例。同样,这也会导致创建比非RESTful设计更多的持久化实体。


C. 使用链接指向任何可以标识的事物

这一点上,我看不出REST和传统的的Web概念有什么明显区别的地方?也许是我的理解不够

D. “标准方法”是否够用?

从文章中可以看出,REST依靠HTTP协议的动词(get/put/delete)来描述对资源的操作,于是在我们的应用端有了很多抽象的标准方法:getAll, delete, getById....。问题是仅仅依靠这些标准方法够吗?

传统的WEB请求是通过在请求中附着参数信息,如XXX.jsp?参数1&参数2,如果我们采用了REST方式的URI描述,对于一些复杂的请求描述,会不会导致描述困难?而且对应的服务器端方法如何定义?毕竟现在很多的交互网站都有大量的自定义查询,仅靠几个简单的CRUD方法定义显然不能满足,那么REST是如何解决的呢?

E. 无状态通信如何实现

这是最令我困惑的一个地方。原文翻译如下:

无状态通信是我要讲到的最后一个原则。首先,需要着重强调的是,虽然REST包含无状态性(statelessness)的观念,但这并不是说暴露功能的应用不能有状态——
事实上,在大部分情况下这会导致整个做法没有任何用处。REST要求状态要么被放入资源状态中,要么保存在客户端上。或者换句话说,服务器端不能保持除了单次请求之外的,任何与其通信的客户端的通信状态。这样做的最直接的理由就是可伸缩性—— 如果服务器需要保持客户端状态,那么大量的客户端交互会严重影响服务器的内存可用空间(footprint)。(注意,要做到无状态通信往往需要需要一些重新设计——不能简单地将一些session状态绑缚在URI上,然后就宣称这个应用是RESTful。)

但除此以外,其它方面可能显得更为重要:无状态约束使服务器的变化对客户端是不可见的,因为在两次连续的请求中,客户端并不依赖于同一台服务器。一个客户端从某台服务器上收到一份包含链接的文档,当它要做一些处理时,这台服务器宕掉了,可能是硬盘坏掉而被拿去修理,可能是软件需要升级重启——如果这个客户端访问了从这台服务器接收的链接,它不会察觉到后台的服务器已经改变了。

对于这个观点我是十分赞成的,应用可以有状态但这个状态的改变,不要依赖于特定的协议状态(比如Session本身就是为了解决HTTP无状态而存在的)。

这里我感兴趣的是实现方式?既然不提倡用协议的状态,又不能在URL附着,那么如何在URI中体现出来呢?如果在URI中暴露出来,会不会令到用户的信息泄露?如果是保存到客户端,除了写cookie和文件好像我没有像到太多别的方法?但是这两种方式经常由于安全原因被用户禁掉

欢迎大家指教!!

最新更新:在JE上看到一篇REST的帖子讨论,非常精彩。虽然是07年的,但是依然有很好的指导意义。解开了不少困惑

http://www.javaeye.com/topic/70113


-------------------------------------------------------------
生活就像打牌,不是要抓一手好牌,而是要尽力打好一手烂牌。
posted on 2010-09-07 11:04 Paul Lin 阅读(1671) 评论(1)  编辑  收藏 所属分类: 其它技术


FeedBack:
# re: 对REST理解上的一些疑问[未登录]
2010-09-15 17:45 | Sam
翻翻以前的哦feed看到你的问题,试着回答下吧。
A. 观点1中这个“ID”如何定义?
我粗略看了下原文,文中并没有提及一定要用URI,不能用URL这种观点。URL和URI的介绍很多,怎么可能没有一个明确的说服呢?
而且,无论用URL或者URI来说明ID如何定义这章节都不冲突。就跟说北京有故宫博物馆和中国有故宫博物馆一样的道理。

B. 要为那些“事物”定义ID?
你的问题是“那么对于这种模式的资源,REST又如何来表示呢?”
我试着回答,假设你有个查询需要查询所有姓为“张”,并且出生日期在1950年前的。那么定义URL的时候,这种集合性的资源ID是后台解析这个查询逻辑的地方定义的。举个例子,老板给你一个feature让你做,这个feature要做很多逻辑。那么老板给你讲的时候,不会把这个case的逻辑说一遍,只会告诉你case名称,这个case名称就是ID。不要想着把整个case的实现逻辑在URI中体现,仅仅定义个ID即可。

C. 使用链接指向任何可以标识的事物
不清楚具体哪个地方不理解,其实这个不用较真。如果你以前写web的时候就已经follow了些类似的REST风格,那么相比就是没太大的区别。
而且就REST的风格来讲,国外的一些大牛们也吵来吵去的。所谓的风格,不局限于一定要按照某种方式去写才叫REST。理解概念,将其应用到web开发中去,外面的人看懂没看懂不一定强制要求,Team内能达成一致并相互理解就算成功。

D. “标准方法”是否够用?
既然叫做标准方法,就是就是解决web开发中一些标准问题,例如CRUD。
当然这个不是绝对的,我曾经看到过一些REST实践的人不用DELETE,GET来做,仅仅用POST就可以实现REST开发,可向其概念与应用存在着并非绝对的关系。
你说的是否够用我想能你从业务角度考虑问题,不是先选技术,再去解决特定业务问题。而是从业务角度寻找最佳技术解决方案。
如果业务系统很大,REST无法完美的解决相应case问题,或者说能够解决但会很复杂。那么你可以考虑基于WSDL的WebService来实现,很多文章都在说两个的区别和应用场景,你可以参考一下。

E. 无状态通信如何实现
这个我这样理解,跳出基于HTML4标准的Web开发方式。想想如下场景:
1. 基于CS模型的客户端开发方式,例如用WPF,SWT,WinForm等。
2. 基于RIA Web框架的开发访方式,例如Silverlight, Flash, JFX等。
3. 基于HTML5的开发模式。
4. 基于脚本语言的开发模式,例如用Ruby或者Grovy访问web等。

以上拙见,就叨叨这些吧。  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航:
 
<2010年9月>
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789

常用链接

留言簿(19)

随笔分类

随笔档案

BlogJava热点博客

好友博客

搜索

  •  

最新评论

阅读排行榜

评论排行榜