almost 4 years ago

本章將淺談:

HTTP Request 與 HTTP Verb

MVC架構 => Rails的基本運作原理

RESTful淺談

模擬要建立一個有 CRUD (Create Read Update Destroy)功能的討論版
在MVC架構下要做什麼東西出來


HTTP Request(請求) 與 HTTP Verb (HTTP動詞)

是瀏覽器端跟網站的 server 之前存取資料的動作,每當我們輸入網址,點擊某個連結,都是代表
我們從瀏覽器端發出請求( request )指令到網站 server 端,後者再以 request 的內容來回應資料給前者
也就是網頁資料的呈現

request只有四個動詞(Verb)種類:

GET POST PUT/PATCH DELETE
讀取 新增 更新 刪除
Read Create Update Destroy

絕大多數都是GET,也就是跟Server端請求讀取某個網址的資料

有要更動到 server 裡資料庫的資料,就會用到另外的三個動作
當我們要用 Rails 做一個有 CRUD功能( CreateReadUpdateDestroy )的討論版
正好就對應到 HTTP Verb 上的四個動詞


MVC架構

『網頁』跟『網站』製作最大的差別,在於前者只有 純讀取 資訊的功能
後者可以運作 CRUD 功能,讓系統功能強大
但從前者走向後者,整個系統的規劃與運作就會變得非常龐大與複雜

為了方便可以區分功能與團隊分工合作將一個網站專案建立起來
近代的網站開發走向了 MVC 架構:

Models Views Controllers
功能 資料庫相關 前端網頁呈現 流程控制與運作

優點是什麼?

可以把整個專案(Project)拆分
負責做前端的人只做 Views
寫流程控制的專心寫 Controllers
所有資料相關集中在 Models

三者之間不互相打架,出問題與狀況也容易追出問題的位置

Ruby on Rails 就是用 Ruby 這個程式語言寫出來的網站 MVC 框架(Framework)


Rails 的運作原理與流程

這張圖可以清楚看出Rails是怎麼跟使用者的瀏覽器互動來運作的

如果我們拿 1-0 所做的 Hello World! 來解釋:

當我們輸入 http://localhost:3000/welcome 這個指令,即是 瀏覽器對server發出讀取(GET)首頁資料的請求(request)

config/routes.rb 裡已經設定好這個Request的工作

config/routes.rb
  
  get 'welcome', to: 'topics#welcome'

Routing(路由)會把這個Request送到 app/controllers/topics_controller.rb

並執行裡面的 welcome 這個動作 (action)

app/controllers/topics_controller.rb
  def welcome
  end

welcome action裡目前沒有存取資料庫(Models部分)的動作,所以會跳至Views

把 app/views/layouts/application.html.erb 裡網站主的樣板抓出來
再把 app/views/topics/welcome.html.erb 裡的資料抓出來,合併在前者的 <%= yield %> 區域裡面


專案開發與資訊安全問題

我們可以任意設定 Action 的命名,只要 Request 正確,就有相對應的動作
但太過自由的設計,會導致專案開發的災難

  1. 若無對 Request 動作分類做統一的規範,一樣的 index action,可能會有不一樣的內容
    導致團隊夥伴在開發時必須花時間閱讀程式碼的內容,也許這個 action 僅需花 1 分鐘
    可是 10 個夥伴,就會花費整個團隊 10 分鐘的時間在這件事上面

  2. 若夥伴或你本人剛做好一個新的 action ,卻發現這個功能之前就做過一個類似的...
    未來若又要沿用這個 action 做延伸功能,要嘛再重讀一次之前的程式碼,不然又要再重做一個新的 action ...

  3. 資訊安全問題,在新增,更新,刪除某筆資料時,必須要有驗證使用者權限的機制
    延續 2nd ,要怎麼知道之前的夥伴是否有做?(花時間重讀) 還是乾脆做一個新的(重複動作)
    又要怎麼讓資訊安全機制不會變成龐大工程,讓團隊精力專心在專案開發上?

最佳解決方案: RESTful


Rails的基礎 RESTful概念

由於RESTful是個很複雜的概念,號稱學 Ruby on Rails 初期最大障礙
本篇儘量用淺顯易懂的方式解釋,如果想了解更多的請到後面的延伸閱讀

以下例子以 2 - 2 , 做出 CRUD 功能的討論版來解釋:

討論版這個功能的名稱: groups
為了要控制它的運作,我們會創建一個新的 Controller檔案 叫做 groups_controller.rb

它是一個用Ruby寫的程式,將好幾個方法(Method, 或稱函式)組成的類別(Class)
以上概念不懂的請回頭看 小弟以前寫的 Ruby 學習心得:1 , 2 , 3

每個 Method 剛好就是本篇文章一開始所說的動作 (action)

HTTP Verb 有四個,除了讀取 (GET) 以外,另外三個都有相對應的動作

  1. 新增 (create)

  2. 更新 (update)

  3. 刪除 (destroy)

在這個功能裡面,我們會做出四個頁面出來:

  1. 首頁(index):用來列出所有的討論版,可以選擇各個單版

  2. 各個討論版專屬頁面(show):顯示討論版版名跟簡介

  3. 修改頁面(Edit):裡面會有表單呈現現有資料來,填完資料後可以送出

  4. 新增頁面(New):裡面會有表單,填完以後可以送出

這七個 action ,是每個CRUD功能裡最基本的動作,缺一不可
只要我們在 controller.rb 裡定義 (Define) 好這七個方法 (Method) 當作動作 (action)

其他的部分 Rails 就會幫我們處理了
像是設定 Routing (路由) 只需要簡單一行:

config/routes.rb
resources :groups

這樣不管瀏覽器端跑來什麼樣的請求 (request) ,Routing都會聰明地幫我們導向正確的 action 去運作後續流程

這樣也解決了資訊安全問題,因為只有 Create Update destroy 這三個action才會動到server端的資料異動

對於網址跟對應的Action與頁面來說

/groups/ 一定就是 index,首頁,對應Routes路徑(或稱為helper): groups_path
/groups/123 一定就是 show,名字為123的討論版個版頁面,對應Routes路徑(或稱為helper): group_path(123)
/groups/123/edit 一定就是 edit,修改討論版123的表單頁面,對應Routes路徑(或稱為helper):edit_group_path(123)
/groups/new 一定就是 new,新增討論版的表單頁面,對應Routes路徑(或稱為helper):new_group_path


總結

所以製作一個RESTful風格的討論版,我們僅需在Routes設定一行程式即可

config/routes.rb
FirstApp::Application.routes.draw do
    resources :groups
end

MVC架構中:

Models:

app/models/group.rb
class Group < ActiveRecord::Base
end

Controllers

在 app/controllers 僅需定義 (Define) 七個方法 (Method) 當動作 (action)

app/controllers/groups_controller.rb
class GroupsController < ApplicationController

  def index
  end

  def show
  end

  def new
  end
  
  def edit
  end

  def create
  end

  def update
  end

  def destroy
  end
end

Views

在app/views/groups/ 資料夾裡做四個html檔案:

index.html.erb

show.html.erb

edit.html.erb

new.html.erb

有沒有發現,Views 裡面的前端 html 檔案剛好都對應到HTTP Verb是GET的action?
當我們運作 Create、Update、Destroy等動作時,Rails不會笨笨的指向開啟"create這個網頁"的動作


這樣我們就用MVC架構把 group 功能完整個拆分出來了

  • Models來做資料庫設定

  • Controllers做流程運作控制

  • Views做前端設計

好處是藉此定下規範:
Views 裡不會出現流程控制
資料存取出狀況找 Models 的部分就對了
Controller 裡面一定不會有html/css/js碼


延伸閱讀:

RESTful應用程式 by iHower

RESTful教學 by Rails102

← [延伸閱讀] CRUD [延伸閱讀] 深度解析 CRUD 功能裡的 Controller & Model →
 
comments powered by Disqus