Restful

Rails从1.2版本就开始实现RESTful了。

什么是REST(Representational State Transfer) 及 RESTFul

REST(Representational State Transfer)软件架构,是由Roy Thomas Fielding博士在2000年首次提出的。直到2005年,随着Ajax、Rails等Web开发技术的兴起,在Web开发技术社区掀起了一场重归Web架构设计本源的运动,REST架构风格得到了越来越多的关注。在2007年1月,支持REST开发的Ruby on Rails 1.2版正式发布,并且将支持REST开发作为Rails未来发展中的优先内容。Ruby on Rails的创始人DHH做了一个名为“World of Resources”的精彩演讲,DHH在Web开发技术社区中的强大影响力,使得REST一下子处在Web开发技术舞台的聚光灯之下。

直到今天,几乎看不到不支持REST开发的Web开发框架了。

所以,要想掌握Rails,REST是必须要理解的概念,除非你回去用Rails1.2之前的版本。

REST软件架构遵循了CRUD原则,该原则告诉我们对于资源(包括网络资源)只需要四种行为:创建(Create)、获取(Read)、更新(Update)和销毁(DELETE)就可以完成对其操作和处理了。

REST的特点有五个:

  • 资源(Resource)
  • 资源的表述(Representation)
  • 状态转移(State Transfer)
  • 统一接口(Uniform Interface)
  • 超文本驱动(Hypertext Driven)

分别代表:

  1. 资源: 是服务器的一种抽象,服务器是由很多离散资源所组成。资源以名词为核心来组织,一个资源可由一个或多个URI来标识,URI既是资源的名称,也是资源的地址。资源可以是系统上的文件、可以是数据库中的表等具体的东西,也可以说其他抽象的东西,只要开发者自己能理解。

  2. 资源的表述: 资源的表述是一段对于资源在某个特定时刻的状态的描述。可以在客户端-服务器端之间转移(交换)。资源的表述可以有多种格式,例如HTML/XML/JSON/纯文本/图片/视频/音频等等。资源的表述格式可以通过协商机制来确定。请求-响应方向的表述通常使用不同的格式。

  3. 状态转移:是指在客户端和服务端之间通过转移代表资源状态的表述(json/html/xml等),来实现操作资源的目的。

  4. 统一接口:REST要求,必须通过统一的接口来对资源执行各种操作。对于每个资源只能执行一组有限的操作。以HTTP/1.1协议为例,HTTP/1.1协议定义了一个操作资源的统一接口,主要包括以下内容:

    7个HTTP方法:GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS

  5. 超文本驱动: 资源之间通过超链接相互关联,超链接既代表资源之间的关系,也代表可执行的状态迁移。

与REST架构风格并行的其他架构风格

  • 分布式对象(Distributed Objects,简称DO) 架构实例有CORBA/RMI/EJB/DCOM/.NET Remoting等等

  • 远程过程调用(Remote Procedure Call,简称RPC) 架构实例有SOAP/XML-RPC/Hessian/Flash AMF/DWR等等

Rails中的REST实现

  • Rails中的每个Controller被看作一个资源
  • 资源的CRUD,Rails默认支持使用HTTP的GET/POST/PUT/DELETE
  • 路由系统和URL Helper 方法生成基于RESTful的超链接

Rails中定义资源, config/routes.rb文件中:

resources :photos

Rails中action和http 方法的对应表:

HTTP Verb Path action used for
GET /photos index 显示所有的photos资源
GET /photos/new new 返回一个创建新photo的页面
POST /photos create 创建一个新的photo资源
GET /photos/:id show 显示一个指定的photo资源
GET /photos/:id/edit edit 返回一个编辑指定photo资源的html页面
PATCH/PUT /photos/:id update 更新一个指定的photo资源
DELETE /photos/:id destroy 删除一个指定的photo资源

注: PATCH只有Rails4支持。

上面的表中,我们可以看到Rails的action对应的HTTP方法,是符合RESTful的。

再看看Rails提供的URL Helper方法:

  • photos_path 生成的path: /photos
  • new_photo_path 生成的path: /photos/new
  • edit_photo_path(:id) 生成的path: /photos/:id/edit (例如, edit_photo_path(10) 生成的path: /photos/10/edit)
  • photo_path(:id) 生成的path: /photos/:id (例如, photo_path(10) 生成的path: /photos/10)

小结:

RESTful架构,我自己的理解,用一句话简单的描述:

用HTTP本身提供的方法来响应服务器资源,并来修改其状态,就是RESTful的。

比如 GET http://www.xxx.com/photos 就是要获取photos的所有资源。

非RESTFul的方式是这样的,拿RPC风格来举例: GET或POST请求, http://www.xxx.com/get_photos 而这个get_photos是你自己定义的,别人也可以定义为get_all_photos,一点都不统一。并且忽略了HTTP方法本身的意义。

所以,RESTful,叫重归Web架构设计本源。

对于这个概念,也要求大脑里先有这个概念,后面我们再慢慢深入。

那么REST架构和MVC架构是否冲突?

我觉得不冲突, MVC是来描述系统内部的代码组织与数据流向,而REST架构,是一种Web Service接口规范。一个是内部,一个是外部。