这本书的前面三章主要讲了一下基本概念,客户端程序,和Amazon的S3,这篇博客总结一下第四章,个人感觉有很多重要的概念。
面向资源的架构(The Resource-Oriented Architecture),这里的资源必须要有一个URI,资源和URI的关系:一个资源可能有一个或多个URI,而一个URI只能指定一个资源。
Restful WS的特性:
1、可寻址性(Addressability)
资源通过URI来暴露给用户,可寻址性是最基本的特性。由于可寻址性,你可以把URI保存在你的书签里,你可以把链接发给别人,而不用把Html文件下载下来发给别人,也可以通过URI对资源进行缓存。
2、无状态性(Statelessness)
无状态性意味着每个HTTP请求是完全隔离的。每次客户端发送请求都必须带上所有服务器端需要的信息。
无状态的应用更容易分布到有负责均衡的多台服务器上;无状态性也更容易缓存:缓存工具只需要看这一个请求,和任何其他请求无关。
应用状态和资源状态(Application State Versus Resource State)
应用状态位于客户端,而资源状态位于服务器端,对于客户端,每个客户端都有各自的应用状态,例如:在google搜索,你可能搜索某个单词且当前页是第3页,我可能搜索另一个单词且在第一页,所以每个客户端都有一个应用状态。当客户端发起请求的时候,必须告诉服务器你的应用状态,比如你当前要看某个单词搜索结果的第几页,服务器端返回结果上有其他链接,这些链接客户端可能作为未来的请求。
而对于资源状态,对于每个客户端都是相同的,就是服务器上的资源。
3、表述性(Representations)
表述性,就是资源的表现形式,相同的资源可以有不同的表述性,比如同一个bug列表可以用XML文档表示,也可以用文本方式表示等等。对于同一资源的不同的Representation,如何知道客户端请求哪一种呢?作者建议不同的Representation使用不同的URI。
4、连通性(Links and Connectedness)
简单点说,就是返回的结果中有对其他资源的链接(URI),比如google搜索,搜索结果可能有其他页的链接。
5、统一的接口(The Uniform Interface)
也就是说Restful WS使用HTTP的基本方法作为他的方法的表示,主要使用HTTP的四个方法:GET,PUT,DELETE,POST。HEAD和OPTIONS用的比较少。
取得某个资源的表述的时候使用GET。
创建一个新的资源的时候,PUT到一个新的URI,或者POST到一个已经存在的URI。
修改资源,使用PUT到存在的URI。
删除资源使用DELETE。
PUT和POST都可以创建新的资源,那有什么区别呢?POST可以创建从属资源,如一个webblog程序通过资源(/weblogs/myweblog)暴露每个blog,而某个blog下面的条目作为从属资源为/weblogs/myweblog/entries/1,当你需要增加一个条目的时候,你可以POST到父资源/weblogs/myweblog,同样PUT也可以完成这个工作,在这里POST和PUT的区别是:当客户端可以控制新资源的URI的时候,则使用PUT,比如blog的下面的某篇文章使用名字来访问,如/weblogs/myweblog/entries/restful_ws_1(这样某个博客下面的文章不能重复),则当你发表一篇新文章的时候,可以PUT到新的URI如/weblogs/myweblog/entries/restful_ws_2来创建资源。而如果客户端不能控制URI的时候,比如blog是通过服务器端某个序列号来访问,客户端是无法知道下一个序号是什么,这时只能使用POST,这种POST如果创建成功,则返回201,响应头中的Location可以保护新创建资源的URI。
还有一个区别,POST对某个存在的资源更新时,一般是追加(append),比如说对某个日志文件做POST,则把日志追加到原日志的后面。如果是PUT则进行的是替换,所以PUT是等幂的,而POST不是(后面会讲)。
安全(Safety)
GET和HEAD方法只是获取资源的表述,所以是安全的。当然也可能有一些副作用,比如有些服务端会记录GET的次数等。
等幂性(Idempotence)
等幂性简单点说就是一次请求和多次请求,资源的状态是一样。比如GET和HEAD,不论你请求多少次,资源还是在那里。请注意,DELETE和PUT也是等幂的,以为对同一个资源删除一次或者多次,结果是一样的,就是资源被删除了,不存在了。为什么说PUT也是等幂的?当你PUT一个新资源的时候,资源被创建,再次PUT这个URI的时候,资源还是没变。当你PUT一个存在的资源时,更新了资源,再次PUT的时候,还是更新成这个样子。在PUT更新的时候,不能做相对的更新(依赖资源现在的状态),比如每次对一个数加1,这样资源状态就会变化。应该每次更新成某个数,比如把某个数变成4,则无论多少次PUT,值都是4,这样就是等幂了。
我们设计Restful WS的时候,GET,HEAD, PUT, DELETE一定要设计成等幂的。由于网络是不可靠的,安全性和等幂性就显得特别重要。如果一次请求,服务器收到处理以后,客户端没有收到相应,客户端会再次请求,如果没有等幂性保障,就会发生意想不到的问题。
POST是不安全也不等幂的,还是拿weblog的例子,如果两次POST相同的博文,则会产生两个资源,URI可能是这样/weblogs/myweblog/entries/1和/weblogs/myweblog/entries/2,尽管他们的内容是一摸一样的。