RESTful的理解

RESTful的理解

http://www.cnblogs.com/rollenholt/p/3693229.html

REST(Representational State Transfer ),有中文翻译为"具象状态传输"(也有:"代表性状态传输")。是由 Roy Thomas Fielding博士 在2000年就读加州大学欧文分校期间在学术论文中提出的一个术语。他首次系统全面地阐述了REST的架构风格和设计思想。这篇论文是Web发展史上一篇非常重要的技术文献,他也为WEB架构的设计与评判奠定了理论基础。

中文版论文下载地址:http://ishare.iask.sina.com.cn/f/20790836.html

REST 定义了一组体系架构原则,您可以根据这些,包括使用不同语言编写的客户端如何通过 HTTP 处理和传输资源状态。所以在事实上,REST 对 Web的影响非常大,由于其使用相当方便,已经普遍地取代了基于 SOAP 和 WSDL 的接口设计。在多年以后的今天,REST的主要框架已经开始雨后春笋般的出现。

个人理解:

(一)  首先REST只是一种风格,不是一种标准

(二)  REST是以资源为中心的

(三)  REST充分利用或者说极端依赖HTTP协议

一.对于今天正在吸引如此多注意力的最纯粹形式的 REST Web 服务,其具体实现应该遵循以下基本设计原则:

1.1.显式地使用不同的 HTTP 请求方法

1.2.无状态

1.3.公开目录结构式的 URI(通过逻辑URI定位资源)。

1.1.显式地使用不同的 HTTP 请求方法

 

我们在 Web 应用中处理来自客户端的请求时,通常只考虑 GET 和 POST 这两种 HTTP 请求方法。实际上,HTTP 还有 HEAD、PUT、DELETE 等请求方法。而在 REST 架构中,用不同的 HTTP 请求方法来处理对资源的 CRUD(创建、读取、更新和删除)操作:

若要在服务器上创建资源,应该使用 POST 方法。

若要检索某个资源,应该使用 GET 方法。

若要更改资源状态或对其进行更新,应该使用 PUT 方法。

若要删除某个资源,应该使用 DELETE 方法。

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

读取) [GET] 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 应用来说非常重要。

1.2.无状态

在 REST 的定义中,一个 Web 应用总是使用固定的 URI 向外部世界呈现一个资源。

它认为Web是由一系列的抽象资源组成,这些抽象的资源具有不同的具体表现形式。

譬如,定义一个资源为photo,含义是照片,它的表现形式可以是一个图片,也可以是一个.xml的文件,其中包含一些描述该照片的元素,或是一个html文件。 并且这些具体的表现可以分布在不同的物理位置上。

1.3.通过逻辑URI定位资源

实现这种级别的可用性的方法之一是定义目录结构式的 URI。

此类 URI 具有层次结构,其根为单个路径,从根开始分支的是公开服务的主要方面的子路径。 根据此定义,URI 并不只是斜杠分隔的字符串,而是具有在节点上连接在一起的下级和上级分支的树。

例如,在一个收集photo的相册中,您可能定义类似如下的结构化 URI 集合:

http://www.example.com/photo/topics/{topic}

如:http://www.example.com/photo/topics/home

根 / photo之下有一个 /topics 节点。 该节点之下有一系列主题名称,例如生日照片,聚会照片等等,每个主题名称指向某个讨论线。 在此结构中,只需在 {topic}输入某个内容即可容易地收集讨论线程。

在某些情况下,指向资源的路径尤其适合于目录式结构。 例如,以按日期进行组织的资源为例,这种资源非常适合于使用层次结构语法。

此示例非常直观,因为它基于规则:

http://www.example.com/photo/2010/02/22/{topic}

第一个路径片段是四个数字的年份,第二个路径片断是两个数字的月份,第三个片段是两个数字的日期。这就是我们追求的简单级别。 在语法的空隙中填入路径部分就大功告成了,因为存在用于组合 URI 的明确模式:

http://www.example.com/photo/{year}/{day}/{month}/{topic}

从而不需要我们去这样去传递信息:http://www.example.com/photo?year=xxxx&day=xxx$month=xxx&topic=xxxx

二.Restful web service的优点:

2.1 HTTP头中可见的统一接口和资源地址

通过对于HTTP Head 的解析,我们便可以了解到当前所请求的资源和请求的方式。这样做对于一些代理服务器的设置,将带来很高的处理效率。

REST 系统中所有的动作和要访问的资源都可以从HTTP和URI中得到,这使得代理服务器、缓存服务器和网关很好地协调工作。而RPC模型的SOAP 要访问的资源仅从 URI无法得知,要调用的方法也无法从HTTP中得知,它们都隐藏在 SOAP 消息中。

同样的,在REST系统中的代理服务器还可以通过 HTTP 的动作 (GET 、 POST)来进行控制。

2.2 返回一般的XML格式内容

一般情况下,一个RESTful Web Service将比一个传统SOAP RPC Web Service占用更少的传输带宽。

2.3 安全机制

REST使用了简单有效的安全模型。REST中很容易隐藏某个资源,只需不发布它的URI;而在资源上也很容易使用一些安全策略,比如可以在每个 URI 针对 4个通用接口设置权限;再者,以资源为中心的 Web服务是防火墙友好的,因为 GET的 意思就是GET, PUT 的意思就是PUT,管理员可以通过堵塞非GET请求把资源设置为只读的,而现在的基于RPC 模型的 SOAP 一律工作在 HTTP 的 POST上。而使用 SOAP RPC模型,要访问的对象名称藏在方法的参数中,因此需要创建新的安全模型。

三. 使用REST架构

  对于开发人员来说,关心的是如何使用REST架构,这里我们来简单谈谈这个问题。REST带来的不仅仅是一种崭新的架构,它更是带来一种全新的Web开发过程中的思维方式:通过URL来设计系统结构。REST是一套简单的设计原则、一种架构风格(或模式),不是一种具体的标准或架构。到今天REST有很多成功的使用案例,客户端调用也极其方便。

下面是我通过Spring3.0来举个例子:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

@Controller

public class ArticleController { 

  

    @RequestMapping(value = "/article/{category}/{id}", method = RequestMethod.GET) 

    public ModelAndView loadArticle(@PathVariable String category, @PathVariable int id, 

            @RequestParam(value = "mode", required = false) String mode) { 

          // ...

    

  

    @RequestMapping(value = "/article", method = RequestMethod.GET) 

    public ModelAndView loadArticleCategories() { 

        // ...

    

  

    @RequestMapping(value = "/article", method = RequestMethod.DELETE) 

    public ModelAndView delArticleCategories() { 

         // ...

    

  

    @RequestMapping(value = "/addarticle", method = RequestMethod.POST) 

    public ModelAndView addArticleCategories(Category category) { 

        // ...

    

  

    @RequestMapping(value = "/addarticle/{name}", method = RequestMethod.POST) 

    public ModelAndView addArticleCategoriesForName(@PathVariable String name) { 

         // ...

    

  

  

然后使用Spring提供的RestTemplate来调用这些服务:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

@Component("articleClient"

public class ArticleClient { 

  

    @Autowired

    protected RestTemplate restTemplate; 

  

    private final static String articleServiceUrl = "http://localhost:8082/articleservice/"

  

    @SuppressWarnings("unchecked"

    public List<Category> getCategories() { 

        return restTemplate.getForObject(articleServiceUrl + "article", List.class); 

    

  

    public Article getArticle(String category, int id) { 

        return restTemplate.getForObject(articleServiceUrl + "article/{category}/{id}", Article.class, category, id); 

    

  

    @SuppressWarnings("unchecked"

    public void delCategories() { 

        restTemplate.delete(articleServiceUrl + "article"); 

    

  

    @SuppressWarnings("unchecked"

    public List<Category> postCategories() { 

        Map<String, String> params = new HashMap<String, String>(); 

        params.put("name", "jizhong"); 

        return restTemplate.postForObject(articleServiceUrl + "addarticle/{name}", null, List.class, params); 

  

    

  

  

提示一下:使用RestTemplate来验证Controller层是一个很不错的选择。

需要注意的是:

RestTemplate 默认并不支持对 DELETE 方法使用请求体。

因为RestTemplate 默认是使用 spring 自身的 SimpleClientHttpRequestFactory 创建请求对象和对其进行相关设置(如请求头、请求体等),它只支持 PUT 和 POST 方法带请求体,RestTemplate 的 DELETE 方法不支持传入请求体是因为 JDK 中 HttpURLConnection 对象的 delete 方法不支持传入请求体(如果对 HttpURLConnection 对象的 delete 方法传入请求体,在运行时会抛出 IOException)。

我们可以通过修改 RestTemplate 的 RequestFactory 实现 delete 方法对请求体的支持。具体实现可以参考:http://blog.csdn.net/hemingwang0902/article/details/9152431

参考资料:

1.     利用 Spring MVC 和 RestTemplate 实现 CorsProxy

http://www.dozer.cc/2014/03/use-spring-mvc-and-resttemplate-impl-corsproxy/

=========================================================================

在RESTful的Web世界里,我们真正可以操作的Request类型其实很少,HTTP仅提供了寥寥无几的几种Request,其中绝大多数Web操作都是由以下四种Request来完成的:

  1. HTTP GET: 获取资源
  2. HTTP PUT/POST: 创建/添加资源
  3. HTTP PUT: 修改资源
  4. HTTP DELETE: 删除资源

本文将介绍上述四种Request类型的使用,同时也会简略介绍HEAD与OPTIONS请求。

参考书籍:《RESTful Web Services》, Chapter 4, “The Resource-Oriented Architecture”

GET, PUT和DELETE

GET请求用于向Server端获取资源,而DELETE请求则用于删除Server端的某个资源。GET的Response一般包含资源的内容,而DELETE的Response可能包含一些状态信息(删除成功或者失败),也可能什么都不包含。 比如:GET /web/blog/3 这个请求会获取第三篇blog的内容,而DELETE /web/blog/3 这个请求则会删除第三篇blog。

PUT请求用于在Server端创建新的资源 (create),或者对已有资源进行修改 (modify)。PUT请求中一般会包含该新资源的内容。 比如:PUT /web/blog 这个请求会在Server端创建一个新的资源,资源名称是blog;而PUT /web/blog/3 这个请求则会修改第三篇blog(用新的内容来覆盖旧的)。

POST

POST请求也可用于在Server端创建新资源,但是在RESTful的世界里,POST请求被定义为创建“从属资源”(拥有父资源的资源) (add)。这话比较拗口,看一下例子可能会清晰很多:

在Server端没有/web/blog的情况下,使用PUT /web/blog请求可以在Server端创建blog资源。blog资源创建好之后,可以使用POST /web/blog来添加一篇新的blog文章,POST请求成功后,我们就拥有了/web/blog/1这个资源。假如当前已经有了三篇blog (/web/blog/1, /web/blog/2和/web/blog/3),那么POST /web/blog将在Server端添加第四篇blog文章(/web/blog/4) — 在这个场景中,/web/blog/1, /web/blog/2, /web/blog/3和/web/blog/4都是“从属资源”(拥有/web/blog这个父资源的资源)。

如何来判断某次Request涉及的资源是从属资源呢?除了从概念逻辑上判断外,还有一个简便的方法来判定:对于POST请求来说,将要被添加的“从属资源”是URI未知的 — 在POST /web/blog请求添加新的一篇blog文章的时候,client并不知道这会是第几篇blog,也不知道该blog创建后的URI是什么(/web/blog/35? 还是/web/blog/42?)。与此相反,PUT请求创建、修改资源的时候,client端清楚的知道对应的URI (PUT /web/blog可以创建blog资源;在/web/blog已经存在的情况下,PUT /web/blog可以修改blog资源的设置;而PUT /web/blog/3则可以对某一篇特定的blog文章进行修改)。

除了添加新的“从属资源”,POST请求还有一种应用场景:对某个特定资源增补内容(append)。比如,对于第三篇blog,在blog的最后,添加一段内容 (POST /web/blog/3)。

对于PUT和POST的区别,我们总结为:

PUT用于创建(Create)或修改(Modify),而POST用于添加(Add)或增补(Append)

根据上述总结可推论,在PUT和POST的属性之间,还有一个重要的区别:PUT是幂等的(Idempotent),而POST不是 — 同一个操作连续进行多次,对于PUT而言其效果与只进行一次相同,但对于POST而言,每一次操作都会对Server端产生影响。

HEAD和OPTIONS

HEAD请求用于获取某个资源的元数据(metadata)–比如,该资源是否存在,该资源的内容长度是多少等等。

OPTIONS请求用于获取某个资源所支持的Request类型,在OPTIONS请求的Response中会包含Allow头信息,比如:

Allow: GET HEAD

上述例子表示该资源只支持GET请求与HEAD请求。

值得注意的是,在OPTIONS请求中,不同的Request头信息会影响最终返回的Response结果。比如,在OPTIONS请求中加入正确的Authorization信息,得到的访问权限就可能更高。

时间: 2024-12-17 00:17:14

RESTful的理解的相关文章

RESTful架构理解

理解RESTful架构 作者: 阮一峰 日期: 2011年9月12日 越来越多的人开始意识到,网站即软件,而且是一种新型的软件. 这种"互联网软件"采用客户端/服务器模式,建立在分布式体系上,通过互联网通信,具有高延时(high latency).高并发等特点. 网站开发,完全可以采用软件开发的模式.但是传统上,软件和网络是两个不同的领域,很少有交集:软件开发主要针对单机环境,网络则主要研究系统之间的通信.互联网的兴起,使得这两个领域开始融合,现在我们必须考虑,如何开发在互联网环境中使

RESTful 架构理解

REST中的关键词: 1.资源 2.资源的表述 3.状态转移 资源: "资源",可以是一段文本.一张图片.一首歌曲.一种操作.你可以用一个URI(统一资源定位符)指向它,每种资源对应一个特定的URI.要获取这个资源,访问它的URI就可以,因此URI就成了每一个资源的地址或独一无二的识别符. 网站的访问,就是与网站一系列的"资源"互动,调用它的URI. 资源的表述 资源的表现形式称作资源的表述. 比如,文本既可以用txt格式表现,也可以用HTML格式.XML格式.JS

对 RESTful 的理解

REST 全称 Representation State Transfor (资源表现层状态改变) 实际上是指客户端通过http/https协议手段来改变URI的状态转化,达到请求不同的资源的目的. 包括 : 1 每个URI代表一种资源 2 客户端和服务器之间,传递这种资源的数据和状态的转化 3 客户端通过http 的请求方式来对服务器资源进行操作,实现表现层的状态转化 RESTful API 定义接口的处理方式:通过对http 路径的定义以及状态码来达到请求资源的目的.

restful阶段性理解

参考:http://www.cnblogs.com/rollenholt/p/3693229.html (一)  首先REST只是一种风格,不是一种标准 (二)  REST是以资源为中心的(她有GET,POST,PUT,DELETE请求方法) 基本设计原则 1.1.显式地使用不同的 HTTP 请求方法 1.2.公开目录结构式的 URI(通过逻辑URI定位资源). 优点 2.1 HTTP头中可见的统一接口和资源地址 2.2 返回一般的XML格式内容 一般情况下,一个RESTful Web Serv

[转载] 理解RESTful架构

原文: http://www.ruanyifeng.com/blog/2011/09/restful.html 理解RESTful架构 作者: 阮一峰 日期: 2011年9月12日 越来越多的人开始意识到,网站即软件,而且是一种新型的软件. 这种"互联网软件"采用客户端/服务器模式,建立在分布式体系上,通过互联网通信,具有高延时(high latency).高并发等特点. 网站开发,完全可以采用软件开发的模式.但是传统上,软件和网络是两个不同的领域,很少有交集:软件开发主要针对单机环境

Restful API的设计与实践

Restful这个名称应该很多人都不陌生,但是我发现不少人对Restful存在或多或少的理解偏差,其中不泛比较厉害的程序员,所以有必要为Restful来"正名". Restful是一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件.它主要用于客户端和服务器交互类的软件.基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制.(详见百度百科介绍) Restful的关键是抽取资源,使用URL与资源进行对应.这边也是多数人理解有偏差之处,即Restful应该理解

RESTful 架构详解

1. 什么是REST REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移. 它首次出现在2000年Roy Fielding的博士论文中,Roy Fielding是HTTP规范的主要编写者之一. 他在论文中提到:"我这篇文章的写作目的,就是想在符合架构原理的前提下,理解和评估以网络为基础的应用软件的架构设计,得到一个功能强.性能好.适宜通信的架构.REST指的是一组架构约束条件和原则." 如果一个架构符合REST

论单页Web应用+RESTful规约[上]

单页Web应用 概述 单页Web应用并不是突然诞生的一门新技术,而是web展示的一种新的尝试.它将所有的动作局限于一个Web页面,在加载站点首页的时候就加载站点需要的JavaScript和CSS.单页Web应用不会随着用户的操作而重新加载页面或者进行页面跳转,而是利用默默执行在后端的JavaScript动态的变换HTML内容,从而对用户动作做出响应.单页Web应用可以提供非常流畅的用户体验,并且在移动端Hybrid应用中有着Native应用的体验. 原理 根据RFC 1738中对URL的描述,U

初识Restful架构

1.对Rest(Restful)的理解 http://www.ruanyifeng.com/blog/2011/09/restful.html https://www.zhihu.com/question/28557115 https://en.wikipedia.org/wiki/Representational_state_transfer 2.Rest(Restful)架构的设计原则 http://www.infoq.com/cn/articles/rest-introduction ht