# 2.2 REST 架構
## 概要:
本課時結合 Rails 路由(routes),詳解 Rails 如何實現 REST 架構。
## 知識點:
1. REST
1. CRUD
## 正文
### 2.2.1 什么是 REST
[REST](http://zh.wikipedia.org/wiki/REST),Representational State Transfer, 更準確地表述應該是:具有代表性的狀態轉移。這是一種軟件架構風格。說它是風格,表明它不具備約束。你可以破壞它,不按照它的風格去實現。但是,REST 擁有簡潔的設計理念,按照它的設計可以在開發中獲得益處。
Rails 是按照 REST 風格設計的,從[1.2版本](http://weblog.rubyonrails.org/2007/1/19/rails-1-2-rest-admiration-http-lovefest-and-utf-8-celebrations/)起,Rails 就開始按照 REST 架構管理資源。
如何管理呢?Rails 從以下三個方面對資源進行定義:
1. 直觀簡短的資源地址:URI,比如:[http://example.com/resources/。](http://example.com/resources/。)
1. 可傳輸的資源:Web 服務接受與返回的互聯網媒體類型,比如:JSON,XML ,YAML 等。
1. 對資源的操作:Web 服務在該資源上所支持的一系列請求方法(比如:POST,GET,PUT或DELETE)。
在我們的代碼里,我想你已經在上一節創建的項目里體驗到了如何增加,修改,和刪除一個商品。
以上引述于[http://zh.wikipedia.org/wiki/REST](http://zh.wikipedia.org/wiki/REST),并結合 Rails 做了解釋。這里還有一篇文章,推薦閱讀:[如何獲取(GET)一杯咖啡——星巴克REST案例分析](http://www.infoq.com/cn/articles/webber-rest-workflow)
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/](http://example.com/resources/) | 列出 URI,以及該資源組中每個資源的詳細信息(后者可選)。 | 使用給定的一組資源替換當前整組資源。 | 在本組資源中創建/追加一個新的資源。 該操作往往返回新資源的URL。 | 刪除整組資源。 |
| 單個資源的URI,比如[http://example.com/resources/142](http://example.com/resources/142) | 獲取 指定的資源的詳細信息,格式可以自選一個合適的網絡媒體類型(比如:XML、JSON等) | 替換/創建 指定的資源。并將其追加到相應的資源組中。 | 把指定的資源當做一個資源組,并在其下創建/追加一個新的元素,使其隸屬于當前資源。 | 刪除指定的元素。 |
所以,向 `PATCH` 或 `PUT` 的地址是一個具體的資源,比如 `/products/1`,而 Rails 會把請求轉移到 `update` 方法中。值得注意的是:在之前的 Rails 版本中,用的是 `PUT` 動作,4.0 后引入`PATCH`,稍微不同的是,patch 可以表示更新或局部更新,但在使用上,和 `PUT` 無異。[[1](http://guides.rubyonrails.org/4_0_release_notes.html#general)]
`: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 手冊](http://guides.rubyonrails.org/routing.html#singular-resources) 中的 routes 章節。
### 閱讀
[REST服務開發實戰](http://www.infoq.com/cn/articles/dt-rest-service)
[為啥REST如此重要?](http://www.csdn.net/article/2013-08-01/2816424-Why-REST-is-so-important)
- 寫在前面
- 第一章 Ruby on Rails 概述
- Ruby on Rails 開發環境介紹
- Rails 文件簡介
- 用戶界面(UI)設計
- 第二章 Rails 中的資源
- 應用 scaffold 命令創建資源
- REST 架構
- 深入路由(routes)
- 第三章 Rails 中的視圖
- 布局和輔助方法
- 表單
- 視圖中的 AJAX 交互
- 模板引擎的使用
- 第四章 Rails 中的模型
- 模型的基礎操作
- 深入模型查詢
- 模型中的關聯關系
- 模型中的校驗
- 模型中的回調
- 第五章 Rails 中的控制器
- 控制器中的方法
- 控制器中的邏輯
- 第六章 Rails 的配置及部署
- Assets 管理
- 緩存及緩存服務
- 異步任務及郵件發送
- I18n
- 生產環境部署
- 常用 Gem
- 寫在后面