Web Service實踐之REST vs RPC

工程師WWW發表於2015-05-30

點選 下載pdf閱讀.

摘要

Web Service 已經不再新鮮, 而隨後的 SOACloud Computing 也不斷出現, 直到百度也 提出了自己的 框計算, 我們尚且不管這些時髦的名詞背後所蘊藏的實際的技術創新有多少, 但是他們終究是逃不出一點, 即 如何解決訪問服務的問題, 而此處的服務通常不在本地而是在 遙遠的你不知道的美國或者印度.

本文想闡述標題中提到的兩種解決遠端服務訪問的方法,優缺點及其一些實際的建議等.

引入

我們每天都在使用瀏覽器來上網衝浪, 在查詢自己需要的資源, HTTP協議自然是我們使用的最多的 一種, 我們盡情地享受著這種資訊高速路的快感,卻沒有試圖去了解我們是如何獲得這些資源的? 它是一種什麼樣的設計理念?

我們也偶爾會使用 Gtalk來和自己的同事或者朋友來聊天, 我們在給朋友提供資源(資訊)的同時 也獲取著朋友的資源(資訊), 我們是否可曾想過, 這種交流背後又是一種什麼過程呢?

在這網際網路的時代,只要牽扯到獲得非本地的資源, 都會面臨一個問題:

如何訪問服務呢?

讓我們先看看什麼是 Web Service.

Web Service

Web Service 也提出了好久了, 那麼究竟什麼是 Web Service ?

簡單地說, 也就是伺服器如何向客戶端提供服務.

常用的方法有:

  1. RPC 所謂的遠端過程呼叫 (面向方法)
  2. SOA 所謂的面向服務的架構(面向訊息)
  3. REST 所謂的 Representational state transfer (面向資源)

SOA 是前幾年炒的很火的一個詞, 不亞於當前的 Cloud Computing , 如果說 RPC 是基於方法呼叫(method),那麼 SOA 則是基於 訊息, 基於方法呼叫通常會與特定的程式語言 耦合起來,而後者則與具體的實現語言無關, 所以在一定程度上得到大公司的支援.

本文不會在 SOA 上著筆過多, 主要是因為筆者本人對這個沒有多少研究, 怕誤導讀者. 另, 筆者 最近對 RPC 和 REST 方式的原理和實現有一些研究, 所以本文會主要集中在 RPC 和REST.

RPC

RPC 即遠端過程呼叫, 很簡單的概念, 像呼叫本地服務(方法)一樣呼叫伺服器的服務(方法).

通常的實現有 XML-RPC , JSON-RPC , 通訊方式基本相同, 所不同的只是傳輸資料的格式.

(如果你已經習慣於XML繁重的尖括號,你不妨可以嘗試下更加輕型,高效,傳輸效率高的 JSON.)

一個簡單的通訊過程通常為:

Request

<?xml version="1.0"?>
<methodCall>
  <methodName>member.get_username_by_id</methodName>
  <params>
    <param>
        <value><i4>1</i4></value>
    </param>
  </params>
</methodCall>

Response

<?xml version="1.0"?>
<methodResponse>
  <params>
    <param>
        <value><string>Zhu Tao</string></value>
    </param>
  </params>
</methodResponse>

向伺服器傳送一個過程呼叫的方法及其引數, 得到伺服器返回的方法執行的結果.

在 XML-RPC 之後又有了更加強大的 SOAP , 用於一些比較複雜的系統之上.

REST

終於我們來看 REST 了, 呵呵, 這個是我目前比較喜歡的一個遠端通訊方法(架構).

REST 不是一種協議,它是一種架構, 一種 Web Service 能夠如果滿足 REST 的幾個條件, 通常就稱這個系統是 Restful 的.

這裡提到的條件包括:

  1. C/S結構 (這是Internet服務的一個基本特徵)
  2. 無狀態 (很熟悉吧,呵呵)
  3. 可以cache (想起了瀏覽器?)
  4. 分層系統 (想起了無數的架構?)
  5. 統一的介面 (如果這是可能的,程式設計師有福了, :D)
  6. code on demand(可選, 其實是一種擴充套件性的要求)

看了這幾個特徵後,你想起了什麼?

你可能會破口而出: HTTP.

我答: You got it!

HTTP是WWW的最核心的協議, 它將簡單的分佈於世界各個角落的資源都統一起來, 統一的地址, 簡單的方法, 和一定數量的表達方式.(你可能對這三點描述很模糊,請go ahead).

REST 的三個要素是 唯一的資源標識簡單的方法 (此處的方法是個抽象的概念), 一定的表達方式.

看下圖:

https://i.iter01.com/images/7c585c658e03495869038fd666fe38b47828253a8502569ee3f73feef53825c0.jpg

圖一. REST的三角架構(摘自 Restful User Experience )

REST 是以 資源 為中心, 名詞即資源的地址, 動詞即施加於名詞上的一些有限操作, 表達是對各種資源形態的抽象.

以HTTP為例, 名詞即為URI(統一資源標識), 動詞包括POST, GET, PUT, DELETE等(還有其它不常用的2個,所以 整個動詞集合是有限的), 資源的形態(如text, html, image, pdf等)

RPC與REST的區別

如果你想只記住一點,那麼就請記住 RPC是以動詞為中心的, REST是以名詞為中心的, 此處的 動詞指的是一些方法, 名詞是指資源.

你會發現,以動詞為中心,意味著,當你要需要加入新功能時,你必須要新增更多的動詞, 這時候伺服器端需要實現 相應的動詞(方法), 客戶端需要知道這個新的動詞並進行呼叫.

而以名詞為中心, 假使我請求的是 hostname/friends/, 無論這個URI對應的服務怎麼變化,客戶端是無需 關注和更新的,而這種變化對客戶端也是透明的.

至於其它的區別,如對實現語言的依賴, 耦合性等,這些都是上面提到的這個根本區別所衍生的.

讓我們回到引入部分的2個問題. 當你每天使用HTTP衝浪時,你都在使用 REST 與遠端的伺服器進行親密接觸. 當你使用Gtalk和同事朋友溝通時,你則是在享受著 RPC 的便利.

推薦閱讀 Restful User Experience (這個slide是個人認為解釋的最好的) 還有 ReST vs SOA(P).

如何選擇?

通常如果我們是客戶端,我們基本上是沒有選擇的權利的, 服務提供商通常只有一種架構的服務.例如facebook, 人人 網開放的API(使用的是 REST ).

但是倘若我們有幸設計和實現自己的 Web Service 我們該如何選擇呢?

根據筆者自己的經驗和心得, 建議 能夠使用REST就儘量使用REST, 主要基於下面幾個考慮:

  1. 擴充套件性
  2. 鬆耦合(意味著,不用強制要求客戶端去更新相應的程式碼)
  3. 客戶端實現語言無關
  4. 效能
  5. 安全性(例如HTTPS)

當然上述的幾點也並非 RPC 都不滿足,不過相對而言, REST 更加清晰和簡潔, 再輔以 JSON 相應的服務會在效能和穩定性(簡單通常意味著robust)方面有很大的提高.

一個自己的專案例子

我們公司正在做一個social game的專案, 我負責整個系統的後端架構和通訊等, 所以仔細地學習和研究了 facebook/人人網開放的API, 由於facebook(人人網完全拷貝facebook)使用的是REST 的架構, 所以即使facebook本身是PHP開發的,這也不妨礙我們使用python來開發, 還有更多的PHP, Java, .net, Perl等客戶端API封裝. (當然人人網是使用Java開發的,我們也使用python).

於是在想,倘若facebook的架構使用的不是 REST ,會有這樣的靈活性嗎? 如果使用的是 RPC 可能 目前我們的日子不會好過, 甚至我們的專案都不可能立項!

另外,因為我們的前端使用的是flash, 與後端的python通訊採用的是 djangoamf , 有意思的是, 如果你瞭解 flash,你會知道AMF是一種二進位制的flash資料互動協議, 而 它是基於RPC ! 當然這正如我上面說的, 某些架構不是我們能夠選擇的, 所以使用 RPC 的結果是如果我們想開放我們遊戲的API(假如我們的遊戲足夠火, 有朋友想基於我們的遊戲開發周邊應用),這就變得很艱難了.但是目前來看,我們開放API的可能性不大.

結論

無論是基於 動詞名詞 或者 訊息, 這些都是為我們提供一個穩定,可靠,安全,易擴充套件的服務為目的的, 所以,如果你有機會為別的客戶端提供開放API(如果你們公司是另一個facebook, twitter),你不妨多考慮下基於 你的平臺的開發者們, 別讓他們的日子不好過啊(同是程式設計師,相煎何太急?呵呵).

歡迎交流.

本文的rst原始碼

本文的原始碼連結在 這裡 .

點選 下載pdf閱讀.

相關文章