本課時結(jié)合 Rails 路由(routes),詳解 Rails 如何實現(xiàn) REST 架構(gòu)。
REST,Representational State Transfer, 更準(zhǔn)確地表述應(yīng)該是:具有代表性的狀態(tài)轉(zhuǎn)移。這是一種軟件架構(gòu)風(fēng)格。說它是風(fēng)格,表明它不具備約束。你可以破壞它,不按照它的風(fēng)格去實現(xiàn)。但是,REST 擁有簡潔的設(shè)計理念,按照它的設(shè)計可以在開發(fā)中獲得益處。
Rails 是按照 REST 風(fēng)格設(shè)計的,從1.2版本起,Rails 就開始按照 REST 架構(gòu)管理資源。
如何管理呢?Rails 從以下三個方面對資源進行定義:
在我們的代碼里,我想你已經(jīng)在上一節(jié)創(chuàng)建的項目里體驗到了如何增加,修改,和刪除一個商品。
以上引述于http://zh.wikipedia.org/wiki/REST,并結(jié)合 Rails 做了解釋。這里還有一篇文章,推薦閱讀:如何獲取(GET)一杯咖啡——星巴克REST案例分析
REST是資源管理的模式,和 SOAP 和 XML-RPC 相比更加簡潔,下一節(jié),我們介紹Rails 是如何管理資源的。
首先,我們在 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
這個文件中。
當(dāng)我們 GET /products
這個地址時,調(diào)用的是 index
方法,當(dāng)我們 POST /products
地址時,Rails 會按照 REST 的模式,把請求轉(zhuǎn)入到 create
方法內(nèi)。我們看一下這個表:
HTTP 請求方法在RESTful Web 服務(wù)中的典型應(yīng)用
資源 | GET | PUT | POST | DELETE |
---|---|---|---|---|
一組資源的URI,比如http://example.com/resources/ | 列出 URI,以及該資源組中每個資源的詳細(xì)信息(后者可選)。 | 使用給定的一組資源替換當(dāng)前整組資源。 | 在本組資源中創(chuàng)建/追加一個新的資源。 該操作往往返回新資源的URL。 | 刪除整組資源。 |
單個資源的URI,比如http://example.com/resources/142 | 獲取 指定的資源的詳細(xì)信息,格式可以自選一個合適的網(wǎng)絡(luò)媒體類型(比如:XML、JSON等) | 替換/創(chuàng)建 指定的資源。并將其追加到相應(yīng)的資源組中。 | 把指定的資源當(dāng)做一個資源組,并在其下創(chuàng)建/追加一個新的元素,使其隸屬于當(dāng)前資源。 | 刪除指定的元素。 |
所以,向 PATCH
或 PUT
的地址是一個具體的資源,比如 /products/1
,而 Rails 會把請求轉(zhuǎn)移到 update
方法中。值得注意的是:在之前的 Rails 版本中,用的是 PUT
動作,4.0 后引入PATCH
,稍微不同的是,patch 可以表示更新或局部更新,但在使用上,和 PUT
無異。[1]
:format
表示我們可以接受和響應(yīng)對應(yīng)的 format 請求。比如 /products/1
響應(yīng)的是 html,而 /products/1.json
響應(yīng)的是 json。
我們可以關(guān)閉這種響應(yīng),只需要 resources :products, format: false
。
或者更改響應(yīng),只接受和響應(yīng) json,如:resources :products, format: 'json'
。
在實踐中,這對 API 的設(shè)計非常方便,比如頁面上 ajax 調(diào)用 /api/users/1/status
,約束它只返回 json 格式。
從現(xiàn)在開始,我們的代碼主要集中在 app 文件夾內(nèi)。下一節(jié),我們將深入 Rails 的 routes 中,看看實踐中經(jīng)常遇到的情況,以及如何解決。你也可以請先閱讀以下 Rails 手冊 中的 routes 章節(jié)。