2012-07-27 38 views
3

所以,我正在學習Ruby on Rails。我獲得了應用程序體系結構的RESTful方法的基礎知識,但我還沒有完全構建一個RESTful應用程序。Rails的REST實現如何被認爲是REST?

在傳統的Web應用程序中,冪等請求(不會改變任何狀態)通過HTTP的GET方法進行,所有非冪等請求通常通過POST方法進行。爲了區分不同的動作,可能會觸發一個POST請求,通常在POST請求中包含表單中的隱藏字段,例如action=deleteaction=add_to_foo_file。這是一個相當簡單的架構,今天很常見,但REST方法讓我們遠離這一點,並建議這個「讓我們發佈一切!」設計被認爲是有害的。

相反,RESTful架構具有我們通過其唯一地識別它們(名詞)和HTTP請求方法(動詞)中的URI操縱資源,而不是確定什麼動作基於在所述請求中的獨立字段採取:

GET => show the resource 
PUT => update the resource 
POST => create a new resource 
DELETE => destroy the resource 

所以現在我們來到Ruby on Rails。在Rails中,PUTDELETE由JavaScript實現,它將鏈接更改爲帶有隱藏字段_method的表單。通過POST從瀏覽器接收表單,然後Rails查找該字段並決定是否將請求路由到控制器的PUTDELETE方法。

等等,什麼?這聽起來很像 - 甚至完全一樣 - 傳統Web應用程序的行爲,該應用程序通過POST接收所有狀態更改請求,並檢查特定字段以決定是銷燬還是修改記錄。

那麼,怎樣才能Rails的做法可以說是REST風格在所有,因爲引擎蓋下,它僅僅是一個重新實施其REST具體試圖從移開‘我們的崗位一切’的做法呢?

此外,不會阻止我的Rails應用程序對於在瀏覽器中關閉了JS的人士降級嗎?

回答

4

什麼使系統RESTful與其使用的動詞不是很多,但事實上交互是由超媒體驅動的(在這種情況下,這包括按需編碼(code-on-demand) JavaScript的)。

您引用的GET/PUT/POST/DELETE映射適用於CRUD操作,但不一定適用於所有內容(並不一定適用於所有瀏覽器)。設計一個RESTful系統是一個合理的經驗法則,但這既不夠充分也不必要。 (當人們想要「RESTful」URI時,它與人們所堅持的想法在同一類別中:沒有這種東西)。

部分屬於RESTful Web Services等書籍的影響。這本書是一本很好的書,但是在WS - */SOAP占主導地位的時候,所有東西都通過POST進行了挖掘。對SOAP的反應是讓人們意識到他們可以使用其他HTTP動詞。

對於REST,真正重要的是尊重URI概念背後的概念,每個HTTP動詞的語義(沒有副作用,冪等請求,......在適當的情況下,以及如果您使用的是HTTP )和HATEOS原則。這是一種架構風格,不要過多關注JavaScript在底下的POST/PUT/DELETE操作。

你當然應該閱讀這些:

編輯:(以下評論)

什麼我應該說是這樣的:如果大多數框架轉向DELETE http://server.tld/resource/1POST http://server.tld/resource/1?_method=DELETE,那麼有什麼優勢的做法只是在首位使用POST http://server.tld/resource/1?my_method=delete超過 ?

  • 它使得總體目標一點點清潔/清晰,在API設計方面。 REST框架最終只能像使用REST框架那樣,因爲REST是架構風格,而不是協議或實現。
  • 另外,嚴格來說,URI包含查詢組件,所以http://server.tld/resource/1http://server.tld/resource/1?my_method=DELETE原則上可以識別不同的資源(儘管這不是一個好的設計選擇)。
  • 該框架能夠直接暴露DELETE/PUT,但通過POST爲不支持它的客戶端提供回退解決方案。

    原因是支持DELETE/PUT的客戶將能夠使用它們,並對其使用情況做出假設。對於客戶而言,將請求視爲非冪等性的問題並不是一個問題,即使它在原理上是冪等性的,而不是冪等性的。如果客戶認爲它可以發送至多1個請求(非冪等),當它可以發送N + 1個請求時,這不會引起重大問題;如果客戶認爲它可以發送N + 1次相同的請求,而這個請求不應該是冪等的,那麼這可能會導致很多問題。模擬PUTPOST是好的,你只是沒有充分利用PUT,仿效POSTPUT會有問題。

+0

+1,優秀的答案。 – 2012-07-27 20:25:34

1

Rails當然支持正確的HTTP動詞(很快甚至PATCH)。唯一的問題是:瀏覽器不支持GET和POST。爲了規避這個限制,Rails提供了額外的功能,用你所描述的_method參數「覆蓋」實際的HTTP動詞。

使用API​​的主要和正確方法是通過實際的HTTP動詞來代替。有了有能力的客戶,你可以並且被鼓勵去做這件事。

至於第二個有關優雅退化的問題,開發人員應確保您的應用在任何情況下對您都很重要。如果您希望您的應用程序在沒有JavaScript的情況下工作,您可以隨時創建實際的HTML表單和提交按鈕。生成的Javascript鏈接只是另一種方式,如果你真的想有一個鏈接創建一個PUT。再一次,Rails認爲這不是什麼好事,但它是一種避開當前所有瀏覽器實施所施加限制的方法。

+0

另外,JavaScript不是僅僅需要添加_method參數。您可以使用隱藏的表單字段。 – 2012-07-27 19:07:32

+1

@RobDavis:事實上,當解析Rails表單助手的':method'參數時,它會爲表單創建一個精確的隱藏字段。這是推薦的實施策略 – 2012-07-27 19:09:07

1

PUT和DELETE請求的問題是HTML表單不支持它的事實。大多數框架處理的方式是通過POST請求進行隧道傳輸。

你仍然可以執行「curl -X DELETE http://example.com/posts/1」,它仍然可以工作。

雖然有很多關於Rails和Rest的誤解。看看http://en.wikipedia.org/wiki/HATEOAShttp://nicksda.apotomo.de/2010/12/rails-misapprehensions-rest-is-more-than-get-post-put-and-delete/

+0

是的,我知道瀏覽器不處理'PUT'或'DELETE'請求。但是,如果「大多數框架」通過「POST」請求隧道,它仍然是一個'POST'請求,因此不是RESTful,對吧?我很難看到如何通過'POST'請求​​挖掘DELETE'比首先使用'POST'請求​​更好。 – Jazz 2012-07-27 19:14:30

+0

@Jazz,你仍然可以做「curl -X DELETE http:// localhost:3000/posts/1 」,它可以工作。它是RESTful,「_method」用於HTML。 – 2012-07-27 19:22:03

+0

「*但是如果」大多數框架「通過POST請求隧道傳遞它們,它仍然是POST請求,因此不是RESTful,對嗎?*」:你應該真的閱讀'*可以使用POST *'。 – Bruno 2012-07-27 19:25:21