记得有一位朋友曾经问过我这样一个问题:是不是无论传递什么东西都靠URI参数来做,就一定是符合REST风格的。我当时没有完全理解他的意思,便 给了他一个现在看来不甚满意的回复。后来当我理解他的意思后,仔细考虑了产生这个问题的原因,觉得这是由于对在REST中URL所承担职责的一些误解造成 的,那么在闲话REST的第二篇里我就来谈谈REST中资源的标识与发现。我会将自己对基于HTTP和URI的REST架构实现中资源标识符的理解和认识 与大家分享,包括URI在REST中的角色和作用以及怎样去看待查询字符串,同时也希望能借此机会给那位朋友一个满意的解释。另外,由于“基于HTTP和 URI的REST架构实现”这个名称过于罗嗦(尽管它是准确的说法),本文接下来提到REST便是特指这一实现,然而正像我在前一篇里所说的,REST是 一组设计需求集合,它作为一个抽象层面的架构风格不依赖于任何实现细节。

REST是面向资源的,而每个资源之所以被称作为资源是因为他们能 够被识别和利用,这便是统一资源标识符(Universal Resource Identifier)被设计和如此命名的缘由。URI是网络上任何一个对象的名字,而它也仅仅是一个名字而已。URI的功能也正像人名一样,我们可以到 公安局通过姓名查找一个人的详细信息,可以用人名来在与朋友的聊天中指代一个人,而对于这个名字的拥有者来说,他通过名字让别人知道了他的存在,也给了别 人称呼他的方法。到网络世界里,URI就好比是资源的名字,它被用来标识、引用和查找资源,与现实世界中人名不同的是在网络上URI不会重复。一个人可以 有多个名字,同样的一个资源也可以有多个指向它的URI,但是在假设不存在同名同姓的情况下,一个名字只能指代一个人,所以没有一个URI不允许同时指向 两个资源。

URI中的查询字符串也许是误解产生的根源,从表面上看他们似乎将引用一个URI看作是远程过程调用的一个便利写法。虽然在我们 过去基于RPC的编程模式下,这样的认识更加自然,但这却违背了URI设计的初衷。RPC是面向活动或方法的,无论这一方法是一个对象的成员方法还是全局 方法,我们习惯了通过客户端传递参数给他们然后获得返回值的模式,但到了面向资源的模式中,这样的认识便成了理解REST的障碍。对URI本身的“操作” 只存在两种:referencing和dereferencing,前者引用一个URI来指代一个资源,后者表示了通过URI来取回实际对象的命令,而这 一命令的执行是通过HTTP请求完成的。现在我们再以现实生活中的人名来类比一下,在现实世界里,无论我们喊一个人的名字多少次,这个人本身不会改变,他 与名字的关系也不会改变。所以在网络中,无论我们引用一个URI多少次,其指向的逻辑对象也不应该改变。查询字符串是URI的一部分,包含查询字符串的 URI也具有相同的性质。举例来说,http://www.google.com/search?q=REST&start=40永远都表示着“Google中搜索REST结果从第40条开始的若干记录”这一对象,无论引用多少次这一逻辑对象本身都不会改变。这便是URI的幂等性,而 这一性质意味着包含查询字符串的URI的确可以理解为某种方法调用,但是此类方法调用必须在逻辑上不改变URI所指向的对象。比如这样的 URI:http://www.restsample.com/add?title=RESTWIKI,这个URI假设它只被用于POST操作,而每一次 对它引用返回的(如果有返回值)都是一个新建的资源,而其本身不指向任何资源。在RPC中对查询字符串诸如此类对URI的应用,都是由于仅将HTTP作为 一个传输协议来使用造成的,作为传输协议的HTTP仅有request和response两个操作,而为了用这两个操作去模拟企业应用中的CRUD,人们 便想到了查询字符串。但是在REST中,HTTP回到了其应用层协议的地位,对资源的CRUD操作使用HTTP原语来完成,所以REST中的URI也只需 担当它原本的角色,即资源标识与查找。

那么我们回到本文开始时那位朋友的问题:是不是无论传递什么东西都靠URI参数来做,就一定 是符合REST风格的架构?显然不是,而且在REST中传递什么东西都靠URI参数本身就是一种错误的做法,URI在REST中的作用只是标识和发现资 源,它被这样设计的目的是为了满足REST这组约束集合中的约束,是REST决定了URI的使用方式,仅仅依靠URI的使用方法去界定一个架构风格是否为 REST是不妥的。

REST中的URI使得其指代对象是可缓存的,比如上面那个Google搜索的例子,由于其结果在短时间内不会改变,所 以该URI可以被当作KEY缓存此对象。而如果URI隐含了改变对象的意思,那么这样的缓存机制就必须通过其他方式实现。另外,从资源角度出发设计的 URI往往会产生对SEO更友好的结果,URI可以被看作资源的一个最简要描述,也可以在其中包含所优化的关键字。
posted on 2009-06-27 11:38  Nyyrikki  阅读(2151)  评论(5编辑  收藏  举报