REST通俗易懂的解释

07-10-01 banq
                   

REST是什么?

REST是Roy Fielding在他的博士论文[1]中提出的用于描述一种网络系统架构风格的名词术语。它是Representational State Transfer的首字母缩写。

它为什么叫Representational State Transfer?

网页是由资源组成的。资源是我们感兴趣的任何对象。举例来说,波音公司可能会定义一种747资源。然后假定用户用下述URL来访问这个747资源:

http://www.boeing.com/aircraft/747

返回给用户的将是这种资源的一种representation(表现形式)(比如说,Boeing747.html)。这种表现形式使客户端应用具有了一种state(状态)。也就是说,一个资源具有多种表现形式,访问不同的表现形式就使客户端具有了不同的状态。

服务器如何确定返回资源的哪种表现形式?[2]

Ruby On Rails 中是通过分辨 HTTP Request Header 信息来分辨客户端是想要取得资源的哪一种表现形式的数据。

当我们用浏览器访问一个网址时,浏览器会构造一个 HTTP 请求。这个请求有一个头信息,其中包括了本次请求接受何种类型的数据。通常浏览器发送的 HTTP 请求头中,Accept 的值都是 */*,也就说接受服务器返回的任何类型的数据。

因此,只要我们指定一个特定的 Accept 参数,那么服务器就可以通过判断该参数来决定返回什么类型的数据。所以在一个采用 REST 架构的应用中,要获取同一个资源的不同表现形式的数据,只需要使用不同的HTTP 请求头信息就行了。

REST——是一种架构风格而不是一种标准

标准是为了系统交互,所以规定了很多细节、格式什么的,而架构是为了指导系统设计,只是一种原则,没有具体的、硬性的规定。就像C/S、B/S、AJAX一样,REST也只是一种架构风格,它可以指导我们如何设计一种Web系统的架构。尽管如此,REST使用如下标准:

<!--[if !supportLists]-->l <!--[endif]-->HTTP

<!--[if !supportLists]-->l <!--[endif]-->URL

<!--[if !supportLists]-->l <!--[endif]-->XML/HTML/GIF/JPEG/etc(资源表现形式)

经典REST系统

最经典的REST系统就是Web! 不过传统Web通常只考虑 GET 和 POST 这两种 HTTP 请求方法。实际上,HTTP 还有 HEAD、PUT、DELETE 等请求方法。而在 REST 架构中,用不同的 HTTP 请求方法来处理对资源的 CRUD(创建、读取、更新和删除)操作:

<!--[if !supportLists]-->l <!--[endif]-->POST: 创建

<!--[if !supportLists]-->l <!--[endif]-->GET: 读取

<!--[if !supportLists]-->l <!--[endif]-->PUT: 更新

<!--[if !supportLists]-->l <!--[endif]-->DELETE: 删除

经过这样的一番扩展,我们对一个资源的 CRUD 操作就可以通过同一个 URI 完成了:

http://www.example.com/photo/logo(读取)

仍然保持为 [GET] http://www.example.com/photo/logo

http://www.example.com/photo/logo/create(创建)

改为 [POST] http://www.example.com/photo/logo

http://www.example.com/photo/logo/update(更新)

改为 [PUT] http://www.example.com/photo/logo

http://www.example.com/photo/logo/delete(删除)

改为 [DELETE] http://www.example.com/photo/logo

从而进一步规范了资源标识的使用。

通过 REST 架构,Web 应用程序可以用一致的接口(URI)暴露资源给外部世界,并提供对资源的操作服务。这对于以资源为中心的 Web 应用来说非常重要。例如照片共享网站、用户社区等。

REST Web Services的特点

<!--[if !supportLists]-->l <!--[endif]-->客户端-服务器:拉风格的交互模式:消费方把主动获取表示

<!--[if !supportLists]-->l <!--[endif]-->无状态:每个从客户端到服务器的请求必须包含足够的信息使得服务器理解该请求,不需要服务器上存储的上下文信息

<!--[if !supportLists]-->l <!--[endif]-->缓存:为了提高网络效率,响应应该可以被标示成可缓存的或是不可缓存的

<!--[if !supportLists]-->l <!--[endif]-->统一的接口:所有资源通过通用的接口访问(HTTP GET, POST, PUT, DELETE)

<!--[if !supportLists]-->l <!--[endif]-->命名资源:系统由通过URL命名的资源组成

<!--[if !supportLists]-->l <!--[endif]-->互连的资源表示:资源的表示通过URL互相联系起来,从而客户端可以从一个状态转换到另一个

<!--[if !supportLists]-->l <!--[endif]-->层次化的组件:中间件,比如代理服务器,缓存服务器,网关等,可以插入到客户端和资源中间来完成性能和安全等功能

REST Web Services设计原则

<!--[if !supportLists]-->l <!--[endif]-->构建REST Web Services的关键是识别出所有需要对外服务的概念层实体。

<!--[if !supportLists]-->l <!--[endif]-->为每个资源创建URL。资源使用名称形式的URL,而不使用动词形式的URL。

<!--[if !supportLists]-->l <!--[endif]-->对资源进行分类,区分出哪些客户端只能获取,哪些是可以修改的。前者使用HTTP GET来访问,后者使用HTTP POST, PUT和DELETE来访问。

<!--[if !supportLists]-->l <!--[endif]-->所有通过HTTP GET访问的资源必须是没有其他影响的。

<!--[if !supportLists]-->l <!--[endif]-->没有资源是作为孤岛存在的。在资源表示中放入超链接来获取关于资源的更多的信息。

<!--[if !supportLists]-->l <!--[endif]-->逐步的暴露数据。不要在单一的文档中暴露所有数据。提供超链接来获取更多的信息。

<!--[if !supportLists]-->l <!--[endif]-->使用schema来指定响应格式。

<!--[if !supportLists]-->l <!--[endif]-->说明该服务是使用WSDL文档来调用,还是简单的HTML文档。

原文:

http://blog.csdn.net/suen/archive/2007/08/16/1746092.aspx

英文原文:

http://www.xfront.com/REST-Web-Services.html

                   

4
bloodrate
2009-08-06 10:27

对于“资源”“表述”“状态”还是理解不好,一个资源有多种表述

比如没我查看波音747飞机生产规格,然后查看波音747飞机的航班情况

那么我是获得了“波音747飞机”这个资源的的规格和航班两种表述呢,还是获得了“波音747飞机”这个资源的一种表述和“波音747飞机航班”这个资源的一种表述?

taochenpfj
2009-11-05 09:55

我在ibm developerworks 上看到一篇关于restful的解释文章,那篇文章从rest应用的分析到一个具体的应用。

这种没有状态的方式好像挺方便的,但是现实中,我们有那么多的状态该放到哪里呢?用户的请求,以及跟用户相关的基本信息,该如何处理呢?

banq
2009-11-05 10:16

用户状态可以保存在客户端,使用AJAX或cookie或其他小程序比如applet/flash也都可以。