1. 程式人生 > >RESTful和REST-RPC介面風格的差異與實現

RESTful和REST-RPC介面風格的差異與實現

REST風格的介面設計是以資源為核心,這種設計風格非常簡約,也利於理解,比如獲取一個id為259的商戶,其HTTP請求應該像這樣:

GET /Store/259

REST-RPC風格則是以操作為核心,一般只使用HTTP謂詞GET或POST,比如同樣的操作,其HTTP請求像這樣:

GET /Store.get?id=259

如果用介面原型來描述這一操作,則這兩種風格都實現了同一個原型:

Store.get(id) -> Store

可見,對同一個操作來說,REST-RPC風格與REST風格的URL是很容易轉換的;兩者只是請求形式不同,對其處理是完全等價的。

REST風格通過以下HTTP謂詞來表示物件CRUD(增刪改查)操作:

  • GET - 獲取物件列表或明細
  • POST - 新增物件
  • PATCH/PUT - 更新物件(前者只更新指定的欄位,忽略未指定欄位;後者對未指定的欄位當作清空處理)
  • DELETE - 刪除物件

筋斗雲框架同時支援這兩種風格的操作。除了上面已列舉的獲取物件明細操作,還有以下等價操作:

新增物件

介面原型:

Store.add()(name, addr?)

REST風格實現:

POST /Store

name=華瑩小吃&addr=銀科路99號

REST-RPC風格實現:

POST /Store.add

name=華瑩小吃&addr=銀科路99號

兩種風格都是將物件的屬性放在POST內容中。

更新物件

介面原型:

Store.set(id)(name?, addr?)

REST風格實現:

PATCH /Store/259

addr=銀科路88號

REST-RPC風格實現:

POST /Store.set?id=259

addr=銀科路88號

兩種風格也都是將物件的待更新屬性放在POST內容中。

注意:筋斗雲框架中,如果使用REST風格介面,則更新物件操作只用PATCH操作做區域性更新,而不使用PUT操作。

查詢列表

介面原型:

Store.query() -> [ Store ]

REST風格:

GET /Store

GET /Store/

REST-RPC風格:

GET /Store.query

刪除物件

介面原型:

Store.del(id)

REST風格:

DELETE /Store/259

REST-RPC風格:

GET /Store.del?id=259

RESTful或REST-RPC風格呼叫的實現

要支援這兩種呼叫風格並不複雜,需要注意的是,使用php實現時,完整的URL需要帶上指令碼名,像這樣:

GET /api.php/Store.get?id=259
或
GET /api.php/Store/259

一般需要對WEB伺服器經過特殊的Rewrite設定,才能隱去URL中的指令碼部分。如使用Apache時,可在入口指令碼(如api.php)對應目錄的.htaccess中設定:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ api.php [QSA,L]

這樣才能在URL中隱藏指令碼,實現簡約呼叫:

GET /Store.get?id=259
或
GET /Store/259

在php中,只要取到HTTP謂詞(如GET/POST/PATCH等)和URL中的物件呼叫資訊:

$method = $_SERVER["REQUEST_METHOD"];
$path = $_SERVER["PATH_INFO"];

這時取到$method就是GET,而$path就是URL中指令碼後面的內容(不包括URL引數),即/Store.get/Store/259,有了這些資訊,接下來就是進行文字分析了。

還要注意的是,使用Javascript的AJAX方法訪問服務端時,一般只支援GET/POST操作,要允許其它謂詞,服務端應設定HTTP頭,如:

Access-Control-Allow-Methods: POST, GET, OPTIONS