(1)什么是REST和RESTful?
1 REST 是一種分散式超媒體系統(如WWW)的軟體架構風格,你可以想像它是一個良好設計的Web應用程式規則: 一組網路Web頁面(虛擬的狀態機器),其中 Client 透過點選超連結(狀態變換),結果是下個Web頁面(表示應用程式的下一個狀態)。
REST 所描述的網路系統包括三個部份:
data elements (resource, resource identifier, representation)
connectors (client, server, cache, resolver, tunnel)
components (origin server, gateway, proxy, user agent)
REST的一個最重要的觀念就是 resources (特定資訊的資源),每一個 resource 由一個url所表示。
通过http协议客户端就可以通过指定的URL去访问相应的resource.
2 RESTful路由設計是Rails的獨到創新,它使用了REST概念來建立一整組的命名路由(named routes)。
RESTful帶給Rails最大的好處是:它幫助我們用一種比較標準化的方式來命名跟組織Controllers和Actions。在沒有RESTful之前,我們上一章介紹了典型路由設計方式,也就是一個個指定Controller和Action,雖然十分地簡便,但是卻沒有什麼準則。同一個Action讓不同的開發者設計,就很可能放在不同的Controller之下,更常見的是讓一個Controller放太多不相關的Action,造成單一Controller過於龐大。
Rails用這套慣例來大大簡化了路由設定。那程式該怎麼寫呢? 我們在config/routes.rb加入以下一行程式:
resources :events
如此就會自動建立四個命名路由(named routes),搭配四個HTTP動詞,對應到七個Actions。它的實際作用,就如同以下的設定:
get '/events' => "events#index", :as => "events"
post '/events' => "events#create", :as => "events"
get '/events/:id' => "events#show", :as => "event"
put '/events/:id' => "events#update", :as => "event"
delete '/events/:id' => "events#destroy", :as => "event"
get '/events/new' => "events#new", :as => "new_event"
get '/events/:id/edit' => "events#edit", :as => "edit_event"
注意到這七個Action方法的名字,Rails是定好的,無法修改。這一套慣例建議你背起來,你可以這樣記憶:
show、new、edit、update、destroy是單數,對單一元素操作
index、create是複數,對群集操作
event_path(@event)需要參數,根據HTTP動詞決定show、update、destroy
events_path毋需參數,根據HTTP動詞決定index、create
(2)RESTful 的一个小应用,比如下面这个例子:
Step. 1
編輯config/routes.rb,加入一個Resources:
resources :events
請加在上方,routes.rb裡面越上面的規則優先權較高。
Step. 2
編輯app/views/events/index.html.erb,修改各個link_to的路徑:
<% @events.each do |event| %>
<li>
<%= link_to event.name, event_path(event) %>
<%= link_to 'edit', edit_event_path(event) %>
<%= button_to 'delete', event_path(event), :method => :delete %>
</li>
<% end %>
</ul>
<%= link_to 'new event', new_event_path %>
注意到刪除的地方,我們多一個參數:method => :delete。非GET的操作,顧及網頁親和力可以把link_to改成用button_to。link_to如果瀏覽器的JavaScript沒開,就會無法送出GET之外的操作。button_to就無此困擾,因為Rails是產生form標籤夾帶_method參數。
Step. 3
編輯app/views/events/show.html.erb,修改link_to的路徑:
<%= @event.name %>
<%= simple_format(@event.description) %>
<p><%= link_to 'back to index', events_path %></p>
Step. 4
修改app/views/events/new.html.erb的表單送出位置如下:
<%= form_for @event, :url => events_path do |f| %>
在本例中,你也可以完全省略:url參數,Rails可以根據@event推算出路由。
Step. 5
修改app/views/events/edit.html.erb的表單送出位置如下:
<%= form_for @event, :url => event_path(@event), :method => :put do |f| %>
:url和:method也可以省略,Rails會根據@event是新建的還是修改來推算出要不要使用PUT。
Step. 6
修改app/controllers/events_controller.rb,將create Action和destroy Action裡的redirect_to改成
redirect_to events_url
而update Action中的redirect_to改成
redirect_to event_url(@event)
Step.7
一旦完成RESTful之後,我們在上一章一開始設定的典型路由就用不到了,編輯config/routes.rb將以下程式註解掉:
# This is a legacy wild controller route that's not recommended for RESTful applications.
# Note: This route will make all actions in every controller accessible via GET requests.
# match ':controller(/:action(/:id(.:format)))'
前兩行的註解告訴你,這種典型路由已經不被新的RESTful風格所推薦使用。特別是它會讓所有Actions都可以透過GET讀取到.