在目前主流的三種Web服務交互方案中,REST相比於SOAP(Simple Object Access protocol,簡單對象訪問協議)以及XML-RPC更加簡單明了,無論是對URL的處理還是對Payload的編碼,REST都傾向於用更加簡單輕量的方法設計和實現。
REST 指的是一組架構約束條件和原則。滿足這些約束條件和原則的應用程序或設計就是 RESTful。
什么是restful,簡稱rest?
REST :Representational State Transfer,表現層狀態轉換;是以 資源 為中心,使用統一的接口URL,使用GET、POST、PUT、PATCH、DELETE等操作方法,來處理資源。
restful風格的原則條件:
C/S結構、無狀態:
Web 應用程序最重要的 REST 原則是,客戶端和服務器之間的交互在請求之間是無狀態的。
從客戶端到服務器的每個請求都必須包含理解請求所必需的信息。如果服務器在請求之間的任何時間點重啟,客戶端不會得到通知。
可以cache:
此外,無狀態請求可以由任何可用服務器回答,這十分適合雲計算之類的環境。客戶端可以緩存數據以改進性能。
統一的接口:
在服務器端,應用程序狀態和功能可以分為各種資源。
資源是一個有趣的概念實體,它向客戶端公開。資源的例子有:應用程序對象、數據庫記錄、算法等等。每個資源都使用 URI (Universal Resource Identifier) 得到一個唯一的地址。所有資源都共享統一的接口,以便在客戶端和服務器之間傳輸狀態。使用的是標准的 HTTP 方法,比如 GET、PUT、POST 和 DELETE。Hypermedia 是應用程序狀態的引擎,資源表示通過超鏈接互聯。
分層系統:
另一個重要的 REST 原則是分層系統,這表示組件無法了解它與之交互的中間層以外的組件。通過將系統知識限制在單個層,可以限制整個系統的復雜性,促進了底層的獨立性。
當 REST 架構的約束條件作為一個整體應用時,將生成一個可以擴展到大量客戶端的應用程序。它還降低了客戶端和服務器之間的交互延遲。統一界面簡化了整個系統架構,改進了子系統之間交互的可見性。REST 簡化了客戶端和服務器的實現。
以上的原則條件,完全同HTTP吻合!
RPC與REST的區別:
1.RPC通常使用TCP、UDP通訊協議,二進制方式的通訊協議,json序列化;Restful通常使用http通訊協議,json序列化。
2.RPC是以動詞(操作方法)為中心;REST是以名詞(資源)為中心。
3.RPC,在擴展的時侯,不方便。當你要需要加入新功能時,你必須要添加更多的動詞, 這時候服務器端需要實現 相應的動詞(方法), 客戶端需要知道這個新的動詞並進行調用。
REST,方便擴展。以名詞為中心, 假使我請求的是 hostname/friends/, 無論這個URI對應的服務怎么變化,客戶端是無需 關注和更新的,而這種變化對客戶端也是透明的.
4示例:使用qq,向徽信聊天時,使用的是RPC風格;使用瀏覽器,通過http請求服務器資源,都是REST風格。
rpc觀點:
rest以資源為中心,把對資源的操作歸結為八種請求方法;對某些情況的API抽象非常糟糕,比如user login / resetpassword等等,無法順當的融入到restful所定義的規范中的資源中。
restful的信徒,他們會說可以根據這個那個規范,把login / password等也納入為某種資源,然后進行增刪改查。這在我看來,純粹是在解決一些原本不存在,根本不需要解決的問題,純浪費。
所有的接口,服務器端原本就存在有相應的函數,它們本來就有自身的命名空間,接受的參數、返回值、異常等等。
采用輕便的方式暴露出來即可。
無需把一堆函數重新歸納到“資源”,再削減腦袋把所有的操作都映射為“增刪改查”。
對應到web上,rpc的成熟方案非常多,有古老的soap,也有輕量的json rpc。
JSON rpc基本上僅是要求所有的請求必須有msg id,有函數名,然后可定義參數,並且區分返回值與異常;也可定義『命名空間』來對函數模塊做划分。
這與大多數語言的模塊、函數定義相符,使用起來是非常便利的。
很多json rpc是供web前端ajax調用,若前端調用抽象得當,調用遠程API,實際上與調用本地函數無甚區別。
實際上,json rpc也未必需要跟http綁定,即便是在web上,它也可以走web socket,這樣子,前端可以使用同一web socket管道批量發送請求,而服務器端亂序返回結果時,前端也可以根據msg id做准確的回調。
websocket,批量調用,亂序返回,這些都可以顯著提高API的輸出吞吐,這些是在json rpc的設計考量內。
調用更方便,性能也更好,兩全其美是完全可能的。
想當然的為了“快”,為了“簡單”就必須犧牲別的,這是嚴重的思維誤區。
有些方案,純粹就是糟糕的方案。
restful API僅適用與業務非常簡單的場景,比方說,就是為了提供少量數據表單的增刪改查。而這種場景實在是太過簡單,實際中幾乎找不到。
rest觀點:
http vs 高性能二進制協議
http相對更規范,更標准,更通用,無論哪種語言都支持http協議。如果你是對外開放API,例如開放平台,外部的編程語言多種多樣,你無法拒絕對每種語言的支持,相應的,如果采用http,無疑在你實現SDK之前,支持了所有語言,所以,現在開源中間件,基本最先支持的幾個協議都包含RESTful。
RPC協議性能要高的多,例如Protobuf、Thrift、Kyro等,(如果算上序列化)吞吐量大概能達到http的二倍。響應時間也更為出色。千萬不要小看這點性能損耗,公認的,微服務做的比較好的,例如,netflix、阿里,曾經都傳出過為了提升性能而合並服務。如果是交付型的項目,性能更為重要,因為你賣給客戶往往靠的就是性能上微弱的優勢。
微服務的盛行,開放平台的盛行,的確讓RESTful過於“流行”了。你可以看看,無論是Google、Amazon、netflix(據說很可能轉向grpc),還是阿里,實際上內部都是采用性能更高的RPC方式。而對外開放的才是RESTful。
如果你的應用非常簡單,無論用哪種都無所謂了,基本都能滿足要求。
最后:
對外開放給全世界的API推薦采用RESTful,是否嚴格按照規范是一個要權衡的問題。要綜合成本、穩定性、易用性、業務場景等等多種因素。
內部調用推薦采用RPC方式。當然不能一概而論,還要看具體的業務場景。