《 Restful Web Services 》读书笔记
第五章 Designing Read-Only Resource-Oriented Services
有了前面4章在理论上的铺垫,本章用一个假想的服务,来表述如何从面向资源的观点来看待问题。整章是围饶下面两点来说明的:
资源设计的一个大的准则
这里表述了面向对象设计和面向资源设计的一些区别。
REST的统一接口原则,意味着在面向对象设计里被视为动词的事物,在面向资源的设计里必须被视为对象(资源)。 作者举了一个例子来说明这句话的含义,一个reader,想订阅一个column的文章, 那么这个动词,订阅, 不符合统一接口原则, 这里把它视为什么对象呢? 订阅, 就是把reader和column关联起来, 那么就产生了订阅对象 , 一个表示reader和column关系的对象。 这个对象作为一个资源,符合统一接口,可以被创建,获取和删除等。而在传统的面向对象设计里, 订阅这个动作,仅仅是底层数据库的一个表而已,不会做为资源暴露出来的。
在面向资源设计里,所有的对象处理都是通过符合统一接口的资源来实现的。
根据需求创建只读资源的步骤
作者提出了一系列设计步骤(只限统一接口GET HEAD这两个方法)
1. 规划数据集
2. 把数据集划分为资源
对于其中的每种资源:
3. 用URI为该资源命名
4. 设计发给客户端的表示
5. 用超链接和表单把该资源与已有资源联系起来
6. 考虑有哪些典型的事件经过
7. 考虑可能出现哪些错误情况
这些步骤里,体现的是REST的四大原则。
一 规划数据集
数据集,顾名思义, 你想要构建web服务的数据集合,用以展示给别人的数据集合。没有数据集还谈什么web服务,或者说web站点。作者的假想服务是地图服务,那么数据集自然是地图数据了。
这里也没有什么经验之谈, 我本人觉得,这一步和第二步是紧密相连的, 因为此时你只是得到一个无序的集合,只是一些想法,你必须将其划分为资源才会具体起来。
二 把数据集划分为资源
作者把服务暴露的资源分为了三类:
1. 为特别的目的专门预定义的一次性资源
例如,网站首页,是一个独一无二的资源
2. 服务暴露的每一个对象所对应的资源
这个好理解。就是最基本的资源。
3. 代表在数据集上执行算法的结果的资源
例如,google搜索,Google把任何形如[url]http://google.com/search?q=[/url]{query} 的URI转换称一个有关{query}的资源列表。
REST式Web服务通过资源来暴露数据和算法。有关数据的资源经常构成一个层次结构。理解算法资源,需要从该动作的结果方面来考虑,而不是从动作本身来考虑。比如搜索,考虑的是搜索出来的资源结果,而不是搜索这个动作本身。
三 命名资源(设计URI)
到这一步,作者已经为他的假想服务确定了五种资源了。现在就是给这些资源命名,资源是以URI命名的,也就是设计URI. 设计URI的时候要遵守可寻址性,也即,作用域信息要包含在URI里。作者给出了URI设计的三条基本原则:
1. 在路径变量来表达层次结构,比如:/parent/child
2. 在路径变量里加上标点符合,以消除误解: /parent/child1;child2
如果这里作用域信息的次序是重要的,那就用逗号,否则则用分号。上面的child1和child2的顺序是无关紧要的,所以用了分号。假如child1和child2非要表明谁是哥哥,谁是弟弟,那么就用逗号: /parent/child1,child2
3. 用查询变量来表达算法的输入,
例如:/search?q=jellyfish&start=20
再例如:[url]http://map.example.com/Earth?show=Shanghai[/url]
搜索地球上所有名叫Shanghai的资源。算法资源是暴露出来的,查询变量来启用(用这个词也许不恰当,我还想到了激活,调用等词语,不知道如何表达了)这个资源。
四 设计表示
当URI设计好之后,要考虑的是当客户端请求一个资源时,服务器应返回什么数据呢 ,画一张什么皮来包装这些数据呢(数据格式,表示)?该格式要能够:
1.传达资源的当前状态
2. 链接到可能的下个应用状态或资源状态(这么做是为了实现‘连通性’)
表示的格式有很多种, 纯文本格式, JSON格式, XML格式, XHTML格式。
这里,我以为作者要选XML格式作为假想服务里星球资源列表的表示格式,但是比较意外的是,作者选了XHTML表示格式,请不要忘记,我们是在设计programmable web, 而不是human web,作者认为XHTML不仅对人类友好,更对程序也友好,XHTML也是可扩展的。这里引出一个微格式(microformats)的概念,可以为XHTML增加语义, 这个特性让我联想到未来的web3.0,使用这种表示格式,在programmable web和human web统一的设计里,语义得以更好的组织和传播(我说的不一定对,只是一个光棍汉天马行空的想法而已)。
在作者的例子里, 对于地球资源, 它的表示传达的只是地球上的一部分地图状态而已,并不是整个地球的地图状态,我们可以通过这个表示里包含的链接来获取地球上其他地方的地图资源。 这个例子表达的意思就是,表示传达资源状态,但它不必传达资源的全部状态,只需要部分状态,加上链接拥有连通性就够了。
这里,作者也展示了如何表示搜索结果列表:
第一点,引用作者的例子, 搜索结果列表当然是跟被‘搜索’的地点(作者列出的一项place资源)相关。
第二点,客户端搜索的地名是不确定的,所以每次搜索都返回一个链接列表,这些链接都是指向地图上具名的地点资源的。
当客户端搜索:/Earth/China%20Shanghai的时候,如何让客户端从这个链接到/Earth/China%20Shanghai?show=diners(上海的所有餐厅)呢,因为不可能列出专门指向餐厅的链接,因为这只是和地点相关无数事物中的一个而已。这里,作者的处理方法是使用一个表单, 因为表示格式是XHTML,所以human web 和 programmable web都是可用的,程序可以通过这个表单来构造URI了。表单的代码见书P136.
五 HTTP响应
现在我们应该考虑,在哪些情况下,响应应该返回错误代码,而不是表示。
作者讲了条件HTTP GET, 实际说的就是支持缓存的应用。说到这里,正好Rails2.2发布,支持了条件HTTP GET, 是个好消息!
这里作者结合假想的地图服务,思考了这个服务里可能会出现哪些错误情况,以及对应的HTTP响应代码,这个对于Programmable web来说比较重要,书里的附录里列出了很多响应代码的使用情景,这里就不记录了。
这个笔记当然略过了书中大部分对假想服务的具体设计过程,记录的只是我的理解和本章表达的思想和框架而已... ...
to be continued ... ...
©著作权归作者所有:来自51CTO博客作者blackanger的原创作品,如需转载,请注明出处,否则将追究法律责任
rubyrailsservices
共同学习,写下你的评论
评论加载中...
作者其他优质文章