首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

REST Service 的最佳实践,第 1 部分 重新解析 REST Service-3

REST Service 的最佳实践,第 1 部分 重新解析 REST Service-3

“缓存”(Cacheable)
为了提高 REST 风格架构的网络性能,Roy 加入了“缓存”的约束。“缓存”不是一个新的概念,HTTP 协议提供机制,使得“客户端”可以“缓存”一些数据。在“服务器”返回的“响应”中,可以隐式或者显式的指明数据的“缓存”属性,这样,“客户端”可以在未来使用“缓存”下来的数据,减少“客户端”和“服务器”端的交互次数,从而达到提高网络性能的目的。
统一的接口 (Uniform Interface)
这是 REST 风格的架构区别于其他架构的一个最关键的指标,就是 REST 风格的架构对于任意应用,规定了统一的接口定义。接口定义包括四个部分:
  • 1)identification of resources(标识资源);
  • 2)manipulation of resources through representations(通过资源的表示来操作资源);
  • 3)self-descriptive messages(自描述的信息);
  • 4)hypermedia as the engine of application state(超媒体作为应用状态的引擎)
下面分别对这些概念进行解析。
Identification of resources
第一部分“identification of resources”讲了 REST 架构风格的一个最核心的概念“Resource”以及 “Resource”的“identification”。“Resource”是信息系统的一种抽象,可以是任何重要的足以把本身作为一个引用(reference)的事物。从应用的角度看,如果应用的用户需要“创建一个到它链接”,获取或者缓存它的“表示”,或者想对他做些操作,那么都可以创建一个“Resource”。一个“Resource”可以是现实世界的事物,比如一本书,一辆车,一栋房子;也可以是一个虚拟的概念,也可以是一个算法的结果。“identification”是“Resource”的全局唯一的标识,如果“Resource”没有 identification,那么他不能称为“Resource”。用 URI 来表示一个 Resource 的 identification。关于 URI 的最佳实践包括 URI 是自描述的,有结构的,这样可以使得“客户端”可以自己创建一些有预测性的请求。几个比较好的 Resource URI 示例:
1
2
3
4
http://www.example.com/books/123456
http://www.example.com/softwares/im/db2/9.5
http://www.example.com/blog/2010/09/10/1
http://www.example.com/bugs/by-state/new




前面解释了什么是 Resource,怎么用 URI 来标识一个 Resource,下面来看下 Resource 和 URI 的关系,他们之间是不是一一对应的呢?让我们来回答下面几个问题:1)两个 URI 能指向同一个 Resource 么?回答是肯定的。作为程序员,我们都有这样的经历,就是经常做一些 release,让我们考虑这两个 URI: http://www.example.com/releases/3.1.1http://www.example.com/releases/latest,在特定的时刻,他们指向的就是同一个 resource,但是背后的概念是不一样的,一个是指向一个特定的 release 版本号,一个是指向一个随着时间演进的 resource,是两个完全不同的概念。所以一个 resource 可以有一个或者多个 URI 来标识。2)一个 URI 能指向不同的 resource 么?答案是否定的。这和 Universal Resource Identifier 的原则相违背。
Manipulation of resources through representations
接着来看看“Representation”。Representation 是 Resource 的表现形式。Resource 是信息系统的抽象,但是最终必须以人们能理解的一种形式提供出来。可以是一个 XML 文档,HTML 文档,CSV,file 等等。一个 Resource 可以有多种 Representation。那么服务器端怎么知道用户想要哪个 Representation 呢?通常来讲有两种方式:
1)在 resource 的 URI 里面指明,为不同的 Representation 提供不同的 URI。举个例子,我们有个 book 的 resource,我们提供几个不同的 URI 来表示不同的 representation。清单 7、8、9 分别是 XML、JSON、CSV 三种 representation 的 HTTP request 和 response 的示例。
清单 7. Representation 为 XML 的 request 和 response 示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
GET /books/123456/xml HTTP/1.1
Host: example.com

Reponse:
HTTP/1.1 200 OK
Date: Fri, 10 Sept 2010 17:15:33 GMT
Last-Modified: Fri, 10 Sept 2010 17:15:33 GMT
ETag: "2b3f6-a4-5b572640"
Accept-Ranges: updated
Content-Type: text/xml; charset="utf-8"
<book category="CHILDREN">
    <title lang="en">Harry Potter</title>
    <author>J K. Rowling</author>
    <year>2005</year>
    <price>24.99</price>
</book>




清单 8. Representation 为 JSON 的 request 和 response 示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
GET /books/123456/json HTTP/1.1
Host: example.com

Reponse:
HTTP/1.1 200 OK
Date: Fri, 10 Sept 2010 17:15:33 GMT
Last-Modified: Fri, 10 Sept 2010 17:15:33 GMT
ETag: "2b3f6-a4-5b572640"
Accept-Ranges: updated
Content-Type: text/json; charset="utf-8"

[
"book":
{
"title":Harry Potter,
"author":J K. Rowling,
"year":2005,
"price":24.99
}
]




清单 8. Representation 为 CSV 的 request 和 response 示例
1
2
3
4
5
6
7
8
9
10
11
12
13
GET /books/123456/csv HTTP/1.1
Host: example.com

Reponse:
HTTP/1.1 200 OK
Date: Fri, 10 Sept 2010 17:15:33 GMT
Last-Modified: Fri, 10 Sept 2010 17:15:33 GMT
ETag: "2b3f6-a4-5b572640"
Accept-Ranges: updated
Content-Type: text/csv; charset="utf-8"

title,author,year,price
Harry Potter,J K. Rowling,2005,24.99




2) 利用 HTTP 的内容协商(content negotiation)机制。客户端可以利用“Accept”header 指明它希望的内容表示形式。还是拿 book 的例子来说,客户端发的 HTTP 请求如清单 9 所示:
清单 9. 利用 content negotiation 机制请求 representation 的 request 示例
1
2
3
GET /books/123456 HTTP/1.1
Host: example.com
Accept: text/xml




1
2
3
GET /books/123456 HTTP/1.1
Host: example.com
Accept: text/json




1
2
3
GET /books/123456 HTTP/1.1
Host: example.com
Accept: text/csv




对应的 response 和第一种方式相同,所以忽略了。
返回列表