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