由一個問題引起的思考:WEB開發中,使用JSON-RPC好,還是RESTful API好?

起因:

研究zabbix的API設計風格。查看zabbix官網API文檔,可以看到使用的是json-rpc:2.0

隨後搜索到知乎上的一個問題討論:https://www.zhihu.com/question/28570307 即標題中的問題。

 

仔細研究,問題不斷髮散再發散,整理一下,以下內容是看了很多篇相關知識後的個人理解:

 

1、RPC是什麼?

參考:https://www.zhihu.com/question/25536695/answer/221638079

RPC是指遠程過程調用。服務器A要調用服務器B上的某個方法,由於內存空間不同,無法直接調用,需要通過網絡來表達調用的語義和傳達調用的數據。需解決以下問題:

通信問題:在服務器A與B之間建立起TCP連接(有答案說UDP也可以);TCP、UDP是屬於傳輸層的協議

參數的序列化和反序列化:參數通過網絡傳輸,需把服務器A內存裏的內容序列化後進行傳輸。

方法映射:參數中包含着要調用的方法,服務器B必須建立起參數與所要調用方法的映射關係

服務器B執行完方法後返回,同樣經歷上述過程。

 

2、json-RPC是什麼

json-rpc 2.0規範:http://wiki.geekdream.com/Specification/json-rpc_2.0.html

JSON-RPC是一個無狀態且輕量級的遠程過程調用(RPC)協議。 本規範主要定義了一些數據結構及其相關的處理規則。它允許運行在基於socket,http等諸多不同消息傳輸環境的同一進程中。

簡單來說,就是定義了各個RPC各參數規範。如method表示方法,param表示參數。服務器B拿到這個東西就是知道了服務器A要調用什麼方法,參數是什麼。

它是運行在socket、http、websocket等協議之上的。注意http、websocket已經是屬於應用層了。

 

3、什麼是websocket?它和socket有什麼區別?

介紹websocket: https://blog.csdn.net/wwd0501/article/details/54582912

websocket首先是一個應用層協議,這點與http相同。

與http不同的是,它可以建立服務器A與服務器B之間的一個長連接(類似於TCP中的長連接),之後可以發送多個請求。而http每一個請求都是獨立的。據介紹,websocket建立長連接時,使用http,之後的請求與返回,則不需要http協議了。

 

socket是傳輸層與應用層之間的一個抽象層,爲應用層屏蔽了傳輸層複雜的協議。

 

4、什麼是RESTful?

restful是一種API設計風格。這裏可以發現,其實restful和json-rpc其實是沒有可比性的。其對比的應該是RPC.

restful必須依賴於http,因爲它需要http請求的類型(post、get、put、delete)來標榜對該資源進行如何的處理。

restful設計難點:需要將所有的接口抽象成某種資源

如想delete多個id怎麼辦?全部寫在url中嗎(delete沒有body)?不,你應該把刪除多個ID抽象成某個任務(即抽象成另一種資源),然後對這個資源使用post。比如用戶的登錄和登出,不適合對用戶這個資源進行操作,應該抽象成對session這個資源進行操作。

想使用restful必須要有這樣的抽象能力。。

知乎對restful一個總結(個人覺得挺到位的):

看Url就知道要什麼(資源)

看http method就知道幹什麼

看http status code就知道結果如何

 

一定要有以資源爲主體的思維。之前也有人說過restful是名詞,rpc是動詞,大概想表述的也是這個意思。

 

5、知乎中有人說json-rpc性能比restful好?

其實是json-rpc能運行在類似於websocket上,是websocket的性能比http好。這種說法有點問題。

像zabbix,json-rpc底層承載還是使用http,反而需要序列化和反序列化的時間,性能好?不見得吧。

 

6、說回zabbix,其API設計風格到底是咋樣的?

首先,開放的API都是使用http的post方法調用的,post的參數遵循json-rpc2.0的規範。如果把所有的API接口看成一種資源,那它的這個API可以說是遵循了restful風格。

其次,最新奇的一點來了,其API的URL只有一個!!只有一個!!格式如下:

POST http://company.com/zabbix/api_jsonrpc.php HTTP/1.1
Content-Type: application/json-rpc

{"jsonrpc":"2.0","method":"apiinfo.version","id":1,"auth":null,"params":{}}

去看了api_jsonrpc.php,這個php腳本要解決的就是,首先拿到http的body數據,接下來用json-rpc2.0規範去解析,拿到method到底是什麼,接下來去調用相應的方法。這個腳本做的就是RPC中提到的要解決方法映射問題。

 

有意思的是,method全都是以這樣的形式A.B,給人一種感覺,A是類,B是A中某個方法。zabbix中所有的方法都用php腳本實現了,對應的每一個A都是獨立的一個php文件,B是A中的某個方法,且名稱是一一對應的,即無需維護參數中的名稱與調用方法的映射關係。

假設不使用zabbix的Php腳本來實現類似的功能,使用類的getMethod的方式,通過反射來調用個人覺得也是可行,當然方法名稱自然也是要一一對應的。

 

暫時不能理解,爲什麼zabbix要這樣設計(僅用一個URL,在json-rpc的method字段去標註具體的方法)?或者這樣設計的好處在哪裏?知乎上有人這樣說:

我見過最高明的restful設計,是隻使用一個url,然後,用post請求,傳method動詞參數。可謂一個restful在手,打遍天下無敵手。

這難不成說的就是zabbix????

 

最後,引用知乎上的一段話:

所謂代碼風格、接口形式、各種林林總總的格式規定,其實都是爲了在團隊內部形成共識、防止個人習慣差異引起的混亂。JSON-RPC當然也是有規範的,但相比REST實在寬鬆太多了。

如果一個開發團隊規定必須在url裏寫action,所有請求都是POST,可以嗎?當然也沒問題,只是不要拿出去標榜自己寫的是RESTful API就行。

規範最終還是爲了開發者和軟件產品服務的,如果它能帶來便利、減少混亂,就值得用;反之,如果帶來的麻煩比解決的還多,那就犯不上純粹跟風追流行了。(作者:Vincross 鏈接:https://www.zhihu.com/question/28570307/answer/163638731)
 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章