2008年03月13日

REST and RESTfull web service

Tags: rest ajax

過去,我提到 REST 這個字眼時,多半指的是一種常用的 Web-based 應用軟體設計慣例或樣式 (我個人偏好用"慣例"一詞,不過用"樣式/pattern"好像比較專業)。既然是慣例,那在設計和使用上就比較隨興。不過隨著 REST 樣式的大量應用,有愈來愈多案例開始使用更制式化的設計樣式,這些高度制式化的 REST 服務,就稱之為 "RESTful web service"。 "-ful" 這個字尾正是在強調它們的設計方式完全符合 REST 文獻的建議內容。

相對於 RESTful ,以往那種基於慣例與相容性的實作方式,有人就稱為 RPC 。不過說到 RPC ,我第一時間想到的是 Unix 系統的 RPC (Remote Procedure Call),而且它的歷史更為悠久。為了避免混淆,所以我傾向於用 "REST-like" 這個稱呼。


首先我們來看看 REST (REpresentational State Transfer) 是什麼。基本上,它的概念來自於 Roy Thomas Fielding 寫的一篇文章《Architectural Styles and the Design of Network-based Software Architectures》。其概念結合了 HTTP 與 URL 兩種協定,以及如何運用於網路軟體架構設計。

REST 把軟體視為 "資源"(Resource),以 URL (Uniform Resource Locator) 定位資源所在處。資源的使用者則藉由 HTTP 協定中所定義的"方法"(method)操作資源。REST 所稱的軟體,其實是資料與資料處理方法的包裝,也就是 OOP 中的 "個體"、"物件"。同時在 HTTP 中,也定義了四種基本方法,即 GET, POST, PUT, DELETE(除此之外還有一些較不常用的方法,詳細內容請自行參考 HTTP/1.1: RFC 2616)。以上四種基本方法大致上對應了四種資料處理動作,即 Create, Read, Update, Delete (CRUD)。

HTTP MethodData operateDescription
POSTCreateCreate a resource without id.
GETReadGet a resource.
PUTUpdateUpdate a resource or create a resource with id if not existed.
DELETEDeleteDelete a resource

方法回傳的訊息也依 HTTP 分成兩個部份,一個是"狀態碼"(Status Code),另一個則是"資源內容"(Content)。

以 URL 定位資源,根據 HTTP 內容指示操作動作與回應訊息。一個符合上述實作方式的網路服務,就稱之為 RESTful web service 。有些文章則更進一步,將 ATOM 協定也加了進來,主要是看上 ATOM 格式的特點,將之運用於資源內容的更新工作。

對了,有些 RESTful 文章還會強調要透過 HTTP Authorization 限制使用者存取資源的權限,而不是用表單加 Cookie。

不過那畢竟是篇學術文章,有些內容在實務上並不易使用。所以以往我們傾向採用 "更務實的作法"。這就是為什麼現在區分 RESTfull web servie 和 REST-like web service 的原因。

實務上有什麼不同呢?主要是歷史因素,早期的瀏覽器只實作了 HTTP 中的兩種方法,即 GET, POST。這個歷史因素沿續至今,使得絕大多數的 Web 應用服務只接受 GET, POST 兩種方法傳遞的資料。同時把操作方法也放在 GET, POST 的資料欄位中,而不是看 HTTP 的 'method' 。例如:

第一個例子,瀏覽器送出的 HTTP Method 是 GET ,但在 URL 中指示的操作動作是刪除(delete)。第二個例子,瀏覽器送出的 HTTP Method 是 POST ,但在表單欄位中指示的動作是查詢資源(get)。

這些例子的使用方式都不合 HTTP 當初制定的原義。但卻是現在最普遍的設計方式。普遍到什麼程度呢?可以問問身邊負責 Web 軟體開發的朋友,有一半以上不知道什麼 HTTP Method 是指什麼,當然更不知道有 PUT, DELETE 這些內容。

儘管今日的瀏覽器已經實作了其他 HTTP Method ,但是仍然缺乏相對應的簡便調用方法。就以前例而言,我們知道在瀏覽器網址列上輸入 URL 就是以 GET 方法送出需求。在表單的 method屬性中可以指定要用 GET 或 POST 方法送出需求。但要送 PUT 或 DELETE 需求要如何做呢?很遺憾,目前只能透過程序性的手段處理。也就是用 JavaScript 建立一個 XMLHttpRequest 個體(XMLHttpRequest 已經被列入 W3C 工作中,目前的草案參見The XMLHttpRequest Object, W3C Working Draft 26 October 2007,這真是令人樂見的結果),然後在 XMLHttpRequest::open() 方法的第一個參數中指定 HTTP Method。麻煩多了,不是嗎?

現在實務上最常採用的作法是將 URL 對應成 /class/method/id/parameter。我稱之為 "REST-like web service"。我們單單寫 "REST" 時,意義較廣,一般指的就是這種方式。

實務運用上,其實這兩種設計方式的差異不大。一般而言,在 loader 與介面上做一些簡單的修改動作,就可以讓原有的 REST-like web service 同時相容 RESTful web service 。以下是一個 PHP 實作的例子。

Example: Controller
Example: Loader

Posted by shirock at 樂多Roodo! │15:55 │回應(1)引用(1)Programming
樂多分類:學術/學習 工具:編輯本文
Ads by Roodo! 

引用URL

http://cgi.blog.roodo.com/trackback/5692241
引用列表:
大家好,我又來談 REST 了。雖然我早已在過去的實務工作中採用 RESTful 概念,但似乎在國內大多數人眼中, RESTful 還是個陌生的內容。因為我新任職的公司,才剛在專案中採用 RESTful 工作,還要大家去 survey 一下。也就在這過程中,我才發覺大伙兒對 RESTful 的認知還有不少偏差。最主要的一點還是把過去的 REST 作法混進來了。忽略了 RESTful 字尾的 -ful 所代表的意義。 雖然我一年多前在 REST and RESTful web service 就提
RESTful 介面實作示範【石頭閒語】 at 2009年11月5日 00:15
回應文章

這一篇對我來說真的很有幫助,我一直不太懂restful,看完後稍有一點的啟發,但是還是有些細節太懂,不知有沒有更進一步的講解。
Posted by 張勝韋 at 2009年07月17日 08:56