2.2 REST 架构
概要:
本课时结合 Rails 路由(routes),详解 Rails 如何实现 REST 架构。
知识点:
- REST
- CRUD
正文
2.2.1 什么是 REST
REST,Representational State Transfer, 更准确地表述应该是:具有代表性的状态转移。这是一种软件架构风格。说它是风格,表明它不具备约束。你可以破坏它,不按照它的风格去实现。但是,REST 拥有简洁的设计理念,按照它的设计可以在开发中获得益处。
Rails 是按照 REST 风格设计的,从1.2版本起,Rails 就开始按照 REST 架构管理资源。
如何管理呢?Rails 从以下三个方面对资源进行定义:
- 直观简短的资源地址:URI,比如:http://example.com/resources/。
- 可传输的资源:Web 服务接受与返回的互联网媒体类型,比如:JSON,XML ,YAML 等。
- 对资源的操作:Web 服务在该资源上所支持的一系列请求方法(比如:POST,GET,PUT或DELETE)。
在我们的代码里,我想你已经在上一节创建的项目里体验到了如何增加,修改,和删除一个商品。
以上引述于http://zh.wikipedia.org/wiki/REST,并结合 Rails 做了解释。这里还有一篇文章,推荐阅读:如何获取(GET)一杯咖啡——星巴克REST案例分析
REST是资源管理的模式,和 SOAP 和 XML-RPC 相比更加简洁,下一节,我们介绍Rails 是如何管理资源的。
2.2.2 CRUD,资源的增删改查
首先,我们在 Rails 中定义一个资源,我们在 routes 中使用 resources 这个方法:
Rails.application.routes.draw do
...
resources :products
我们运行这个命令:
% rake routes | grep product
products GET /products(.:format) products#index
POST /products(.:format) products#create
new_product GET /products/new(.:format) products#new
edit_product GET /products/:id/edit(.:format) products#edit
product GET /products/:id(.:format) products#show
PATCH /products/:id(.:format) products#update
PUT /products/:id(.:format) products#update
DELETE /products/:id(.:format) products#destroy
Rails 为我们提供了7个方法,他们在 app/controllers/products_controller.rb
这个文件中。
当我们 GET /products
这个地址时,调用的是 index
方法,当我们 POST /products
地址时,Rails 会按照 REST 的模式,把请求转入到 create
方法内。我们看一下这个表:
HTTP 请求方法在RESTful Web 服务中的典型应用
资源 | GET | PUT | POST | DELETE |
---|---|---|---|---|
一组资源的URI,比如http://example.com/resources/ | 列出 URI,以及该资源组中每个资源的详细信息(后者可选)。 | 使用给定的一组资源替换当前整组资源。 | 在本组资源中创建/追加一个新的资源。 该操作往往返回新资源的URL。 | 删除整组资源。 |
单个资源的URI,比如http://example.com/resources/142 | 获取 指定的资源的详细信息,格式可以自选一个合适的网络媒体类型(比如:XML、JSON等) | 替换/创建 指定的资源。并将其追加到相应的资源组中。 | 把指定的资源当做一个资源组,并在其下创建/追加一个新的元素,使其隶属于当前资源。 | 删除指定的元素。 |
所以,向 PATCH
或 PUT
的地址是一个具体的资源,比如 /products/1
,而 Rails 会把请求转移到 update
方法中。值得注意的是:在之前的 Rails 版本中,用的是 PUT
动作,4.0 后引入PATCH
,稍微不同的是,patch 可以表示更新或局部更新,但在使用上,和 PUT
无异。[1]
:format
表示我们可以接受和响应对应的 format 请求。比如 /products/1
响应的是 html,而 /products/1.json
响应的是 json。
我们可以关闭这种响应,只需要 resources :products, format: false
。
或者更改响应,只接受和响应 json,如:resources :products, format: 'json'
。
在实践中,这对 API 的设计非常方便,比如页面上 ajax 调用 /api/users/1/status
,约束它只返回 json 格式。
从现在开始,我们的代码主要集中在 app 文件夹内。下一节,我们将深入 Rails 的 routes 中,看看实践中经常遇到的情况,以及如何解决。你也可以请先阅读以下 Rails 手册 中的 routes 章节。