在本文中,我們將研究?jī)煞N HTTP 通信協(xié)議和 API 設(shè)計(jì)之間的高級(jí)方法;gRPC 和 REST。
大多數(shù)開(kāi)發(fā)人員都非常熟悉 REST,這是因?yàn)?REST 在世界上主要使用,并且在教授 HTTP 編程的初學(xué)者教程中也使用它。因此,默認(rèn)情況下,新開(kāi)發(fā)人員會(huì)熟悉 REST。
大多數(shù)關(guān)于編程語(yǔ)言或框架(如 Reactjs、Angular、PHP 等)的教程在教授客戶端-服務(wù)器通信時(shí)都使用 HTTP。gRPC 很少被使用或提出,因此 gRPC 變得未知,當(dāng)開(kāi)發(fā)人員開(kāi)始深入研究 HTTP 通信時(shí),它就會(huì)被挖掘出來(lái)。
因此,我們將在這篇文章中介紹 REST 和 gRPC,以解釋它們的好處及其工作原理。
REST 概述
REST(REpresentational State Transfer 的縮寫(xiě))是一種架構(gòu)風(fēng)格,旨在幫助創(chuàng)建和組織分布式系統(tǒng)。這一切都始于 2000 年的 Fielding,他致力于開(kāi)發(fā)一種獨(dú)特的客戶端-服務(wù)器通信標(biāo)準(zhǔn)化方法。
REST 使用 HTTP 協(xié)議進(jìn)行通信,它被廣泛用于 Web 應(yīng)用程序中。REST 只是為高層架構(gòu)實(shí)現(xiàn)提供了關(guān)于后端數(shù)據(jù)如何通過(guò) JSON/XML 消息格式提供給客戶端的指南。
API 使用 REST 指南來(lái)提供可供使用的 Web 服務(wù)。REST API 在所謂的資源中提供這些 Web 服務(wù)。資源代表服務(wù)器中的單個(gè)狀態(tài),可以通過(guò)通用接口訪問(wèn),然后可以通過(guò) HTTP 動(dòng)詞獲取或操作:GET、POST、DELETE 和 PUT。
如果系統(tǒng)滿足以下約束,則系統(tǒng)被視為 RESTful:
客戶端服務(wù)器
此約束要求客戶端和服務(wù)器必須獨(dú)立運(yùn)行。服務(wù)器不應(yīng)該依賴(lài)客戶端運(yùn)行,客戶端也不應(yīng)該依賴(lài)服務(wù)器。
服務(wù)器包含服務(wù)器代碼并通過(guò) URL 向公眾公開(kāi)端點(diǎn)。API 端點(diǎn)通常使用 Swagger 等工具發(fā)布在 API 文檔中。
另一方面,客戶端知道 API 端點(diǎn)并調(diào)用它們以完成服務(wù)并獲得響應(yīng)。
這在開(kāi)發(fā)兩個(gè)系統(tǒng)時(shí)提供了很大的靈活性,而不會(huì)相互影響。
根據(jù)Fernando Doglio 在 Node.js REST API 開(kāi)發(fā)中的說(shuō)法:
這種約束背后的主要原則是****關(guān)注點(diǎn)分離****。它允許
將前端代碼(信息的表示和可能的 UI 相關(guān)處理
)與服務(wù)器端代碼分離,服務(wù)器端代碼應(yīng)負(fù)責(zé)數(shù)據(jù)的存儲(chǔ)和服務(wù)器端處理。
客戶端只知道 API 并調(diào)用它們,而無(wú)需知道它們是如何工作的。服務(wù)器服務(wù)是獨(dú)立開(kāi)發(fā)的,它們只是在負(fù)載上提供客戶端可以調(diào)用的接口。
無(wú)國(guó)籍
此約束適用于服務(wù)器不得保存有關(guān)客戶端請(qǐng)求的數(shù)據(jù)。通信必須是無(wú)狀態(tài)的,每個(gè)請(qǐng)求必須包含服務(wù)器的所有信息。
客戶端負(fù)責(zé)將狀態(tài)數(shù)據(jù)保存在其存儲(chǔ)中。
這種約束使系統(tǒng)高度可見(jiàn)且易于檢查和調(diào)試,因?yàn)樾枰赖囊磺卸荚谡?qǐng)求中,而且系統(tǒng)具有高度的可擴(kuò)展性和可靠性。
可緩存
此約束提高了服務(wù)器和客戶端的性能。
在服務(wù)器中,可以緩存影響服務(wù)器 CPU 的高配置服務(wù),例如處理圖像、計(jì)算巨大數(shù)字序列等的服務(wù),這種緩存使其只運(yùn)行一次并緩存結(jié)果,然后在后續(xù)調(diào)用中使用到服務(wù),它從緩存中返回結(jié)果。其他東西可以緩存,例如數(shù)據(jù)庫(kù)請(qǐng)求可能會(huì)變得冗長(zhǎng),結(jié)果可以緩存以備將來(lái)的請(qǐng)求。
在客戶端,高配置會(huì)因高加載時(shí)間而導(dǎo)致性能問(wèn)題。
可能會(huì)有對(duì)狀態(tài)數(shù)據(jù)和其他數(shù)據(jù)的抱怨,可以通過(guò)使用緩存控制、max-age 和到期時(shí)間來(lái)緩解。
這種可緩存的約束使系統(tǒng)具有高性能。
統(tǒng)一界面
此約束涉及使 API 接口與客戶端統(tǒng)一。必須提供 API 接口,以便服務(wù)的消費(fèi)者可以通過(guò) API 接口調(diào)用服務(wù)。
接口是公開(kāi)可用的點(diǎn),因此世界可以與您的資源或服務(wù)進(jìn)行通信。沒(méi)有接口,消費(fèi)者就無(wú)法使用服務(wù)器中的服務(wù)。
它就像一個(gè)執(zhí)行特定工作的庫(kù),工作的實(shí)現(xiàn),即工作是如何完成的,都包含在其中。庫(kù)必須公開(kāi)消費(fèi)者可以用來(lái)執(zhí)行操作的函數(shù)/方法。如果庫(kù)不公開(kāi)函數(shù)/方法,我們就無(wú)法使用庫(kù)。
分層系統(tǒng)
服務(wù)器可以有不同的層,例如我們可以有業(yè)務(wù)邏輯層、存儲(chǔ)層、會(huì)話管理層等。
此約束聲明系統(tǒng)必須分層,以便允許在不同的服務(wù)器上維護(hù)不同的組件。
這些層僅與下面的層通信以獲取其輸入并使用它來(lái)將其輸出傳達(dá)給它上面的層。
通過(guò)將組件分層,我們使服務(wù)器更加靈活,并且在需要時(shí)非常易于維護(hù)和擴(kuò)展。
點(diǎn)播代碼
此約束是可選的。它涉及客戶端能夠從服務(wù)器獲取可執(zhí)行代碼并執(zhí)行它。
這是非常不必要的,因?yàn)榭蛻舳诵枰龅木褪菑姆?wù)器獲取信息并對(duì)其進(jìn)行處理,但是在客戶端是瀏覽器的情況下,它必須下載 JavaScript 代碼,該代碼可以使其能夠處理未來(lái)來(lái)自服務(wù)器的信息。
REST 架構(gòu)的構(gòu)建塊是一種資源。一切都可以成為資源,這取決于服務(wù)器將提供的服務(wù)。這些資源是通過(guò)使用 HTTP 方法的公共接口訪問(wèn)的。
HTTP 動(dòng)詞可用于引用對(duì)資源執(zhí)行的操作類(lèi)型。
- GET 以只讀模式訪問(wèn)資源。
- POST 創(chuàng)建一個(gè)新資源。
- PUT 更新給定的資源。
- DELETE 移除或刪除資源。
如果我們有一個(gè)產(chǎn)品資源,我們將對(duì)該資源執(zhí)行以下類(lèi)型的操作:
- /products GET:獲取所有產(chǎn)品
- /products/:id GET:獲取由 id 指定的給定產(chǎn)品。
- /products:id DELETE:刪除給定的產(chǎn)品。
- /products:id PUT:編輯給定的產(chǎn)品。
- /products POST:創(chuàng)建一個(gè)新產(chǎn)品。
gRPC 概述
gRPC是構(gòu)建在 RPC 協(xié)議之上的最新框架。
gRPC 是一種進(jìn)程間通信,允許連接到分布式應(yīng)用程序并調(diào)用應(yīng)用程序中的本地方法/函數(shù)。
簡(jiǎn)單的說(shuō),gRPC 是 RPC 的擴(kuò)展。在 RPC 中,想法是調(diào)用或調(diào)用遠(yuǎn)程函數(shù)/方法。函數(shù)可以托管在某處的遠(yuǎn)程服務(wù)器上,并且可以從另一個(gè)遠(yuǎn)程服務(wù)器或客戶端機(jī)器調(diào)用,而不必托管在同一臺(tái)服務(wù)器上。
在開(kāi)發(fā) gRPC 應(yīng)用程序時(shí),定義了一個(gè)服務(wù)接口。此服務(wù)接口包含可以使用其參數(shù)和返回類(lèi)型遠(yuǎn)程調(diào)用的方法。此服務(wù)接口還包含調(diào)用這些方法時(shí)將使用的消息格式、方法的參數(shù)和返回類(lèi)型。
所以基本上,服務(wù)定義接口包含消息和方法框架或結(jié)構(gòu)。
有了這個(gè)接口,服務(wù)端服務(wù)就可以實(shí)現(xiàn)這個(gè)接口,提供底層的代碼邏輯。服務(wù)器將提供處理客戶端調(diào)用的方法。
在客戶端,客戶端也會(huì)使用這個(gè)接口來(lái)遠(yuǎn)程調(diào)用函數(shù)。gRPC 框架抽象了所有復(fù)雜性,例如數(shù)據(jù)序列化、網(wǎng)絡(luò)通信、身份驗(yàn)證、訪問(wèn)控制等。用戶對(duì)通信是如何發(fā)生的一無(wú)所知。
根據(jù)我們上面所說(shuō)的,我們可以推斷出 gRPC 服務(wù)具有三個(gè)組件:
- 服務(wù)器
- 服務(wù)定義接口
- 客戶端
gRPC 服務(wù)器可以在任何環(huán)境下運(yùn)行,客戶端也是如此,它可以在任何環(huán)境中運(yùn)行,并且它們都可以用 gRPC 框架支持的不同語(yǔ)言編寫(xiě)。
gRPC 服務(wù)器可以用 Java 構(gòu)建,客戶端可以用 JavaScript 構(gòu)建,它們可以無(wú)阻礙地運(yùn)行和相互通信。gRPC 服務(wù)器可以用 C++ 編寫(xiě),而客戶端可以用 Go 編寫(xiě),它們可以相互通信。這就是 gRPC 在許多應(yīng)用程序中主要受青睞的原因,因?yàn)樗鼈兪?strong>多語(yǔ)言的。
gRPC:協(xié)議緩沖區(qū)
服務(wù)定義接口是使用協(xié)議緩沖區(qū)定義的。
Protocol Buffers 是由 Google 構(gòu)建的開(kāi)源數(shù)據(jù)序列化工具,用于描述數(shù)據(jù)結(jié)構(gòu)并生成表示數(shù)據(jù)的字節(jié)流。
gRPC使用此協(xié)議緩沖區(qū)作為 IDL(接口定義語(yǔ)言)和消息交換格式。這意味著 gRPC 使用協(xié)議緩沖區(qū)來(lái)定義其服務(wù)器要公開(kāi)的方法,例如
service ProductService {
addProduct() returns () {}
removeProduct() returns () {}
getAllProducts() returns () {}
}
上面是一個(gè) proto 文件,它定義了三個(gè)將被客戶端公開(kāi)和調(diào)用的方法。
作為一種消息格式,它定義了類(lèi)型,就像我們?cè)陟o態(tài)類(lèi)型語(yǔ)言中一樣,我們定義類(lèi)型來(lái)顯示類(lèi)、函數(shù)或方法將作為 arg 返回、使用或接收的數(shù)據(jù)的形狀。所以在協(xié)議緩沖區(qū)中,這就是消息傳遞格式的作用。
message ProductRequest {
string id = 1;
}
message ProductResponse {
string name = 1;
}
service ProductService {
addProduct(ProductRequest) returns (ProductResponse) {}
}
帶有消息的對(duì)象是服務(wù)器和客戶端使用的類(lèi)型和消息格式。addProduct 方法必須使用 ProductRequest 數(shù)據(jù)結(jié)構(gòu)調(diào)用,并且它必須返回 ProductResponse 數(shù)據(jù)結(jié)構(gòu)。因此,響應(yīng)客戶端類(lèi)的服務(wù)器和調(diào)用該方法的客戶端都必須遵循 ProductResponse ProductRequest 格式。
gRPC 使用 HTTP/2 進(jìn)行調(diào)用和通信。這允許用戶執(zhí)行傳統(tǒng)的請(qǐng)求-響應(yīng)類(lèi)型的調(diào)用,它還可以執(zhí)行單或雙(雙向)流。
比較和對(duì)比:REST/gRPC
我們已經(jīng)看到了 REST 和 gRPC 的概述,現(xiàn)在我們可以比較和對(duì)比這兩種 HTTP 協(xié)議。
讓我們來(lái)看看 gRPC 和 REST 之間的區(qū)別。
Protobuf 與 JSON
gRPC 和 REST 接收響應(yīng)的格式不同。
REST 使用 JSON 格式接收消息。雖然我們可以接收 XML、原始二進(jìn)制格式等格式的消息,但最佳實(shí)踐和教程使 JSON 成為規(guī)范,而且由于 JSON 靈活、高效、平臺(tái)中立且與語(yǔ)言無(wú)關(guān)。
gRPC 使用 Protobuf 消息格式以消息二進(jìn)制格式發(fā)送請(qǐng)求和接收響應(yīng)。
JSON 和 Protobuf 都與平臺(tái)無(wú)關(guān),這意味著它們可以被開(kāi)發(fā)和使用,而與所使用的平臺(tái)無(wú)關(guān)。
JSON 在系統(tǒng)之間傳輸時(shí)速度較慢。Protobuf 消息傳遞速度更快,因?yàn)橄谕ㄟ^(guò)網(wǎng)絡(luò)發(fā)送之前被編組。編組是將參數(shù)和遠(yuǎn)程函數(shù)打包成消息二進(jìn)制包的過(guò)程。
HTTP/1.1 與 HTTP/2
REST 在通信以及發(fā)送請(qǐng)求和接收響應(yīng)中使用 HTTP/1.1。gRPC 使用 HTTP/2,這對(duì)于進(jìn)程間通信來(lái)說(shuō)甚至更快。
HTTP/1.1 比 HTTP/2 慢。HTTP/2 旨在改進(jìn) HTTP/1.1 的局限性。這使得 gRPC 在請(qǐng)求-響應(yīng)方面比 REST 更快。
REST 在多路復(fù)用方面缺乏更多。REST 一個(gè)接一個(gè)地加載資源,一個(gè)資源必須等到前一個(gè)資源加載完成。gRPC 使用 HTTP/2,它使用 TCP 連接發(fā)送多個(gè)數(shù)據(jù)流,這些數(shù)據(jù)被拆分為二進(jìn)制代碼消息并為消息編號(hào),以便客戶端知道每個(gè)二進(jìn)制消息屬于哪個(gè)流,從而確保沒(méi)有資源被阻塞.
所以我們看到,HTTP/1.1 對(duì)于多個(gè)請(qǐng)求是低效的。
通過(guò)服務(wù)器推送和標(biāo)頭壓縮,gRPC 的 HTTP/2 仍然比 REST 的 HTTP/1.1 提高了性能排名。服務(wù)器推送允許 HTTP/2 在請(qǐng)求之前將內(nèi)容從服務(wù)器推送到客戶端,而 HTTP/1.1 無(wú)法做到這一點(diǎn),服務(wù)器僅在請(qǐng)求時(shí)提供內(nèi)容。Header 壓縮要求 HTTP/2 能夠使用 HPACK 壓縮方法從 Header 中刪除不必要的消息。
流媒體與請(qǐng)求/響應(yīng)
在 REST 中,我們只能執(zhí)行請(qǐng)求并獲得響應(yīng)之類(lèi)的東西。這是由于它用于通信的 HTTP/1.1 協(xié)議在事物的各個(gè)方面都非常有限。
另一方面,正如我們所知,gRPC 使用 HTTP/2 進(jìn)行通信。使用 TCP 連接,HTTP/2 支持來(lái)自服務(wù)器的多個(gè)數(shù)據(jù)流以及傳統(tǒng)的請(qǐng)求-響應(yīng)。
使用 gRPC,我們可以執(zhí)行:
- 客戶端流:這涉及客戶端向服務(wù)器發(fā)送數(shù)據(jù)流。服務(wù)器注冊(cè)以接收來(lái)自客戶端的數(shù)據(jù)流,然后發(fā)送一條消息作為響應(yīng)。
- 服務(wù)器流:客戶端向服務(wù)器發(fā)送一個(gè)單曲,服務(wù)器將打開(kāi)一個(gè)流連接,并隨著時(shí)間的推移向客戶端發(fā)送數(shù)據(jù)流。當(dāng)流到達(dá)時(shí),客戶端將注冊(cè)一個(gè)要注意的事件。
- 雙向流:這是雙向的。服務(wù)器和客戶端可以相互發(fā)送和接收數(shù)據(jù)流。
優(yōu)點(diǎn):gRPC/REST
讓我們看看事情的光明面:
gRPC 優(yōu)勢(shì)
讓我們列出 gRPC 的一些優(yōu)點(diǎn)
- 它是多語(yǔ)種
- 它有雙工流
- 它是強(qiáng)類(lèi)型的。
- 它與平臺(tái)無(wú)關(guān)
- 它使用 HTTP/2,這是對(duì)傳統(tǒng) HTTP 1.1 的升級(jí)
休息優(yōu)勢(shì)
- 它幫助我們構(gòu)建高度靈活的系統(tǒng)。
- 它幫助我們構(gòu)建具有高可見(jiàn)性的高度可擴(kuò)展的系統(tǒng)。
- REST 更易于使用且學(xué)習(xí)速度更快。
底線
沒(méi)有哪個(gè)比另一個(gè)更好,但從表面上看,我們可以得出結(jié)論,gRPC 非常適合大型分布式應(yīng)用程序。gRPC 的一個(gè)缺點(diǎn)是它不是那么受歡迎,所以沒(méi)有多少初學(xué)者教程可以讓開(kāi)發(fā)人員直接使用它而無(wú)需四處亂搞,而且大多數(shù)瀏覽器不支持 gRPC,因此我們必須使用代理工具,例如Envoy幫助我們將請(qǐng)求從瀏覽器代理到 gRPC 服務(wù)器。
REST 仍然很棒,并且被世界各地的公司和開(kāi)發(fā)人員廣泛使用。此外,大多數(shù)新技術(shù)自然支持,這使其成為開(kāi)發(fā)人員和軍團(tuán)的首選。gRPC 被視為未來(lái),因?yàn)樗褂玫募夹g(shù)和技術(shù)帶來(lái)的好處。
那么gRPC over REST?不,我認(rèn)為您選擇了您的用例需要的那個(gè)