API架構的選擇,RESTful、GraphQL還是gRPC

peida發表於2023-05-19

hi,我是熵減,見字如面。

image

在現代的軟體工程中,微服務或在客戶端與服務端之間的資訊傳遞的方式,比較常見的有三種架構設計的風格:RESTful、GraphQL和gRPC。

每一種模式,都有其特點和合適的使用場景,今天,我們主要來對三種風格做一個深入的理解和對比,以方便我們在做技術選型時,能夠做出有效的決策。

RESTful

什麼是RESTful?

RESTful是一種軟體架構風格和設計模式,它是一種輕量級的Web服務實現模式。

REST(Representational State Transfer)代表著“表現層狀態轉移”,它強調使用HTTP協議的GET、POST、PUT、DELETE等動詞來實現資源的增、刪、改、查操作。

image

RESTful是一種基於資源的設計理念,強調在分散式系統中以統一的介面來訪問和操作資源。

RESTful架構風格的特點:是客戶端和伺服器之間的通訊採用無狀態協議,每個請求包含足夠的資訊,使得伺服器不需要保留客戶端的任何上下文資訊,從而可以實現高度的可伸縮性和可靠性。

REST風格的API設計通常具有簡單、輕量級、易於快取和擴充套件等特點。

RESTful架構的原則

Restful架構風格遵循以下幾個原則:

  • 資源(Resource):將應用程式的功能和資料抽象為資源,每個資源都有一個唯一的識別符號(URL)來訪問和操作。

  • 統一介面(Uniform Interface):使用統一的介面來對資源進行操作,包括標準的HTTP方法(GET、POST、PUT、DELETE等)和狀態碼(如200、404、500等)。

  • 無狀態(Stateless):客戶端請求中應包含足夠的資訊,服務端不儲存客戶端的狀態資訊,每個請求都是獨立的,這樣可以實現可伸縮性和可靠性。

  • 按需響應(Cacheable):服務端可以透過設定響應頭中的快取策略,使得客戶端可以快取響應,減少對服務端的請求,提高效能和效率。

  • 分層系統(Layered System):客戶端與服務端之間可以存在多箇中間層(如代理伺服器、負載均衡器等),以實現更高階別的可擴充套件性和安全性。

透過遵循RESTful的原則,可以實現簡單、可擴充套件、易於理解和整合的API設計,促進不同系統之間的互操作性,並支援跨平臺和跨語言的通訊。

image

在現實中,RESTful API已成為構建Web服務和分散式系統的非常常見的實踐。

RESTful的適用場景

RESTful架構風格,適用於各種不同的場景和應用程式型別。

以下是一些RESTful的經典適用場景:

  • Web應用程式開發:RESTful非常適合構建Web應用程式,透過使用HTTP協議的標準方法和狀態碼來操作資源,實現前後端分離、松耦合的架構。

  • 移動應用程式開發:RESTful API提供了移動應用程式與後端伺服器進行通訊的標準化介面,使得移動應用能夠方便地獲取和運算元據。

  • 雲服務和微服務架構:RESTful API是構建雲服務和微服務架構的常見方式,不同的服務透過RESTful介面進行通訊和協作。

  • 物聯網(IoT)應用程式:RESTful API可以用於物聯網裝置之間的通訊和控制,使得裝置能夠透過HTTP請求與雲平臺進行互動。

  • 開放資料介面(Open API):RESTful API可以提供開放的資料介面,供第三方開發者進行整合和構建應用程式。

總的來說,RESTful架構風格非常通用且適用於各種不同的應用場景,特別是在需要構建分散式系統、提供開放介面和實現松耦合架構的應用程式中表現出色。

RESTful的優點

RESTful架構,具有以下優點:

  • 簡單性:Restful架構使用基於HTTP的標準方法和狀態碼,易於理解和學習。它採用了簡潔的URL和資源的概念,使得API的設計和使用變得簡單明瞭。

  • 可伸縮性:Restful架構的無狀態特性使得服務端可以水平擴充套件,每個請求都是獨立的,不依賴於特定的伺服器狀態,從而提高系統的可伸縮性和效能。

  • 可移植性:Restful API是基於標準的HTTP協議和資料格式(如JSON、XML),可以被不同的平臺和程式語言輕鬆支援,促進了跨平臺和跨語言的互操作性。

  • 可見性:Restful API使用明確的URL來表示資源和操作,使得API的結構和功能對開發者和使用者來說更加可見和可理解,降低了學習和使用的難度。

  • 快取支援:Restful API支援HTTP的快取機制,可以使用快取來減少對伺服器的請求,提高效能和效率。

  • 獨立性:Restful架構支援前後端分離,使得前端可以獨立演化和開發,後端服務可以以獨立的方式進行部署和維護。

RESTful的缺點

然而,RESTful架構也有一些缺點:

  • 語義限制:RESTful架構對資源的操作只使用了HTTP的標準方法(GET、POST、PUT、DELETE等),有時可能無法滿足某些複雜的操作需求,需要透過擴充套件HTTP方法或引入自定義操作。

  • 高耦合性:RESTful架構中,客戶端需要對服務端的資源結構有一定的瞭解,資源的結構和URI的設計需要提前約定好,這會帶來一定的耦合性。

  • 安全性:RESTful架構對於安全性的支援相對較弱,需要額外的安全措施(如HTTPS、身份驗證、授權等)來保護API的安全性。

  • 效能問題:當資源的層級結構較深、關聯關係複雜時,可能需要進行多次請求來獲取完整的資料,增加了網路開銷和響應時間。

綜上所述,Restful架構具有簡單性、可伸縮性和可移植性等優點,但在語義限制、高耦合性和安全性方面存在一些限制和挑戰。在設計和選擇API架構時,需要根據具體的應用需求權衡各種因素。

GraphQL

什麼是GraphQL?

GraphQL是一種用於API的查詢語言和執行時環境。它於2015年由Facebook開發並開源,並在業界逐漸得到廣泛應用。

GraphQL的主要目標是提供一種靈活、高效和強大的方式來獲取客戶端所需的資料。

image

與傳統的RESTful API不同,GraphQL允許客戶端透過傳送一個包含所需資料結構的查詢來精確獲取資料,而不需要多次請求不同的端點。

GraphQL的核心是一個查詢語言,透過該語言可以精細地描述需要獲取哪些資料以及資料之間的關係。客戶端透過GraphQL查詢語句向服務端傳送請求,服務端根據查詢語句返回資料。GraphQL的查詢語句可以巢狀、組合和重用,從而實現了更加靈活和高效的資料獲取。

image

GraphQL的原則

GraphQL架構風格的原則,主要包括以下幾點:

  • 單一入口(Single Entry Point):GraphQL的核心思想是透過一個單一的入口點來獲取資料。客戶端可以使用一個GraphQL查詢來獲取所需的所有資料,而不需要多次請求。這樣可以減少網路往返次數,提高效率。

  • 客戶端驅動(Client-Driven):GraphQL採用客戶端驅動的資料查詢方式,客戶端可以靈活地指定需要的資料欄位和關聯關係,從而避免了傳統RESTful介面中的過度獲取或不足獲取的問題。客戶端決定需要的資料,伺服器只提供相應的資料。

  • 強型別(Strongly Typed):GraphQL使用強型別系統來定義資料模型和查詢。透過定義明確的型別和欄位,可以在編譯時進行型別檢查,減少執行時錯誤。這有助於提高開發效率和程式碼質量。

  • 可組合性(Composability):GraphQL具有高度的可組合性,可以透過組合現有的型別和欄位來構建複雜的查詢和資料模型。這種組合性使得GraphQL非常靈活,可以滿足各種不同的資料需求。

  • 實時更新(Real-Time Updates):GraphQL支援實時資料更新和訂閱功能,允許客戶端訂閱資料的變化並接收實時更新。這使得實時應用程式開發更加簡單和高效。

  • 自文件化(Self-Documenting):GraphQL的查詢語言具有自我描述性,即查詢本身就包含了資料模型的描述資訊。這使得客戶端可以直接查詢可用的資料欄位和關聯關係,減少了對文件的依賴。

  • 批次操作(Batching):GraphQL支援批次操作,可以將多個相關的請求合併為一個請求傳送到伺服器。這樣可以減少網路往返次數,提高效率。

  • 資料載入(Data Fetching):GraphQL支援透過資料載入器(Data Loader)來最佳化資料的獲取和處理。資料載入器可以對資料進行批次載入和快取,提高資料獲取的效率和效能。

以上這些原則,有助於設計和構建具有高度靈活性、可組合性和效率的GraphQL架構。透過遵循這些原則,可以實現更好的資料查詢和互動體驗,同時提高開發效率和程式碼質量。

GraphQL的適用場景

GraphQL適用於各種場景和應用程式,特別適用於以下幾類經典場景:

  • 多平臺應用程式:當應用程式需要為多個平臺(例如Web、移動和IoT裝置)提供資料服務時,GraphQL非常有用。透過GraphQL,客戶端可以精確地獲取它們需要的資料,而不需要多個API端點和不必要的資料傳輸。

  • 複雜的資料需求:對於需要獲取和展示覆雜資料結構的應用程式,GraphQL是一個理想的選擇。它允許客戶端根據其需要來精確定義所需的資料欄位和關聯關係,減少了資料冗餘和不必要的查詢。

  • 快速迭代和前後端解耦:GraphQL適用於快速迭代和開發過程中的前後端解耦。前端開發人員可以根據需要靈活地獲取資料,而無需等待後端開發人員提供新的API端點或資料結構的更改。

  • 微服務架構:對於採用微服務架構的應用程式,每個微服務通常有其專門的資料需求。GraphQL可以作為一個統一的資料層,聚合來自多個微服務的資料,並將其以一種一致的方式暴露給客戶端。

  • 實時資料需求:如果應用程式需要實時資料推送和訂閱功能,例如聊天應用程式或實時監控系統,GraphQL提供了訂閱查詢的機制,可以實現實時資料的推送和更新。

  • 個性化資料需求:對於需要根據使用者個性化需求提供定製資料的應用程式,GraphQL是一個理想的選擇。客戶端可以根據使用者的偏好和需求定義查詢,獲取個性化的資料結果。

總之,GraphQL適用於各種不同型別的應用程式和場景,特別適合那些需要靈活、精確和高效獲取資料的場景。它提供了強大的查詢語言和靈活的資料查詢能力,使得客戶端能夠更好地控制所需的資料,從而提供更好的使用者體驗和效能。

GraphQL的優點

GraphQL架構,其具有以下優點:

  • 靈活性和精確性:GraphQL允許客戶端精確地指定需要的資料欄位,避免了傳統RESTful API中的過度獲取和傳輸不必要的資料。這種靈活性使得客戶端能夠更好地控制所需的資料,減少了網路傳輸和資料冗餘。

  • 單一端點:與RESTful API相比,GraphQL只需要一個端點,客戶端可以傳送複雜的查詢請求,並獲得所需的資料結果。這樣簡化了API的維護和管理,減少了網路請求的次數。

  • 強大的型別系統:GraphQL擁有豐富的型別系統,可以定義自定義型別、介面和列舉等。這使得客戶端和服務端之間的資料互動更加明確和可靠,減少了因資料格式不匹配而引發的錯誤。

  • 關聯和巢狀查詢:GraphQL支援在一個查詢中指定多個資源之間的關聯關係,並支援巢狀查詢。這樣可以一次性獲取多個相關資源,減少了多次請求的需求,提高了資料獲取的效率。

  • 快取控制:GraphQL具有內建的快取控制機制,允許客戶端在查詢中指定所需資料的快取策略。這可以提高資料訪問的效能和效率,並減少對伺服器的請求。

  • 實時資料推送:GraphQL支援實時資料推送和訂閱功能,客戶端可以透過訂閱查詢來獲取實時資料更新。這對於需要實時通知和推送的應用程式非常有用,如聊天應用程式或實時監控系統。

GraphQL的缺點

儘管GraphQL架構具有許多優點,但也存在一些缺點:

  • 學習曲線高:相對於傳統的RESTful API,GraphQL具有更復雜的概念和語法。因此,學習和理解GraphQL的概念和工作原理需要一定的時間和精力。

  • 過度獲取資料:由於GraphQL的靈活性,客戶端可能會過度獲取資料,導致查詢結果過於龐大,增加了網路傳輸和資料處理的負擔。

  • 缺乏標準化:與RESTful API相比,GraphQL缺乏一致的標準化規範。這導致不同的實現之間可能存在差異,開發人員需要根據具體的實現來進行學習和開發。

  • 快取管理複雜:由於GraphQL的靈活性和精確性,快取管理變得更為複雜。開發人員需要考慮快取資料的一致性和更新策略,以確保資料的準確性和實時性。

  • 安全性考慮:由於GraphQL允許客戶端靈活地定義查詢,服務端需要特別關注安全性方面的考慮。例如,客戶端可能透過查詢來獲取敏感資料或進行惡意操作。因此,服務端需要實施適當的安全措施,如認證、授權和輸入驗證,以保護資料和系統的安全。

  • 效能問題:儘管GraphQL可以減少網路請求的次數,但對於複雜的查詢和大規模資料集,GraphQL可能面臨效能問題。查詢的複雜性和資料載入的成本可能導致響應時間的延遲。因此,開發人員需要仔細考慮和最佳化GraphQL的查詢效能。

  • 缺無狀態特性:與RESTful API相比,GraphQL沒有內建的無狀態特性。這意味著服務端需要維護客戶端的查詢狀態,以便正確處理查詢和返回一致的結果。這可能增加服務端的複雜性和開發的複雜性。

gRPC

什麼是gRPC

gRPC是一種高效能、開源和通用的遠端過程呼叫(RPC)框架,由Google開發。

gRPC支援多種程式語言和平臺,並使用Protocol Buffers作為預設的訊息編碼協議,可以在不同的應用程式之間實現高效的通訊。

image

gRPC框架基於HTTP/2協議,它支援全雙工的流式傳輸、多路複用、頭部壓縮等特性,可以提供更高效的網路效能和更好的擴充套件性。同時,gRPC也支援多種負載均衡演算法、認證和授權機制,可以保障通訊的安全性和可靠性。

gRPC可以簡化應用程式之間的通訊過程,開發者只需要定義一份IDL(介面定義語言)檔案,然後使用gRPC框架自動生成客戶端和服務端的程式碼。

另外,gRPC預設使用Protocol Buffers作為訊息編碼協議,所以通訊資料的大小比傳統的文字協議(例如JSON)更小,可以提高網路效能。

gRPC的應用場景

gRPC具有廣泛的應用場景,常見的使用場景包括:

  • 微服務架構:gRPC適用於構建微服務架構中的服務間通訊。由於其高效的序列化和跨語言支援,可以實現不同微服務之間的快速、可靠的通訊。

  • 分散式系統:gRPC可以在分散式系統中作為通訊框架使用,用於不同節點之間的資料傳輸和遠端呼叫。它提供了高效的遠端過程呼叫機制,適用於大規模分散式系統的通訊需求。

  • API後端服務:gRPC可以用作構建API後端服務的通訊協議。它提供了強型別和介面定義語言,使得客戶端和伺服器之間可以共享和交流介面定義,方便開發和維護。

  • 實時流式資料傳輸:gRPC支援雙向流式通訊,適用於需要實時傳輸和處理流式資料的場景。例如,實時聊天應用、實時資料分析和實時監控系統等。

  • 高效能運算:由於gRPC使用了高效的序列化和傳輸協議,可以在需要進行高效能運算的場景中使用。例如,分散式計算、機器學習模型的訓練和推理等。

  • IoT(物聯網)應用:gRPC可以在物聯網應用中作為裝置和後端伺服器之間的通訊協議。它的輕量級和高效效能使得它適用於連線大量裝置的場景。

gRPC適用於許多不同的應用場景,特別是在分散式系統、微服務架構和實時通訊方面具有顯著的優勢。它提供了高效、可靠和靈活的通訊機制,使得開發人員可以更輕鬆地構建複雜的分散式應用程式。

gRPC的優點

gRPC架構的關鍵特點,主要包括以下幾點:

  • 高效的遠端過程呼叫(RPC):gRPC使用高效的遠端過程呼叫協議,基於Protocol Buffers(protobuf)進行資料序列化和通訊。透過使用二進位制協議和高效能的序列化機制,gRPC可以實現快速、高效的跨網路通訊。

  • 強型別和介面定義語言(IDL):gRPC使用介面定義語言(IDL)來定義服務介面和訊息格式。IDL提供了一種規範和標準,可以在客戶端和伺服器之間共享和交流。透過IDL,可以明確地定義服務介面和訊息型別,提高跨平臺和多語言的互操作性。

  • 支援多種傳輸協議:gRPC支援多種傳輸協議,包括基於HTTP/2的傳輸和傳統的TCP傳輸。HTTP/2作為底層協議,提供了多路複用、流控制和頭部壓縮等優點,可以提高效能和效率。

  • 支援多種程式語言:gRPC支援多種程式語言,包括Java、C++、Python、Go等,可以滿足不同語言和技術棧的需求。這使得開發人員可以使用自己熟悉的程式語言來實現和使用gRPC服務。

  • 雙向流式通訊(Bidirectional Streaming):gRPC支援雙向流式通訊,即客戶端和伺服器可以同時傳送和接收資料流。這使得實時的流式資料傳輸和通訊成為可能,例如聊天應用、實時監控等場景。

  • 攔截器和中介軟體(Interceptors and Middleware):gRPC提供攔截器和中介軟體的機制,可以在請求和響應的處理過程中插入自定義的邏輯。這樣可以實現日誌記錄、認證授權、錯誤處理等通用的功能,提高程式碼複用性和可維護性。

  • 可擴充套件性和服務發現:gRPC支援服務發現和負載均衡機制,可以根據需要動態地擴充套件服務。透過使用服務發現機制,可以自動發現和管理可用的服務例項,以實現高可用性和負載均衡。

  • 自動生成的客戶端和伺服器程式碼:使用gRPC的IDL和相關工具,可以自動生成客戶端和伺服器的程式碼。這樣可以簡化開發過程,減少手動編寫重複性程式碼的工作量。

這些原則使得gRPC成為一個強大、高效和靈活的RPC框架。透過遵循這些原則,可以實現快速、可靠的跨網路通訊,並提供豐富的功能和特性,滿足不同應用場景的需求。

gRPC的缺點

儘管gRPC具有許多優點,但也存在一些缺點:

  • 學習曲線較陡:相對於傳統的RESTful API和其他通訊協議,gRPC具有一定的學習曲線。使用gRPC需要了解Protobuf和IDL的概念,並學習如何定義服務介面和訊息型別。這可能對於新手或非熟悉這些概念的開發人員來說,需要一定的時間和學習成本。

  • 不適用於所有場景:儘管gRPC在許多場景下表現優異,但並不是適用於所有應用場景。例如,如果你的應用程式需要對公共網路進行通訊,而網路環境受到限制(如防火牆),則可能需要配置特殊的設定來支援gRPC的通訊。

  • 難以除錯和跟蹤:由於gRPC使用二進位制協議和高效的序列化機制,資料在傳輸過程中進行了編碼和壓縮,使得除錯和跟蹤變得更加困難。在排查問題時,可能需要額外的工具和技術來解析和檢視資料。

  • 不適用於所有語言和平臺:儘管gRPC支援多種程式語言和平臺,但並不是所有語言和平臺都得到了廣泛的支援。某些語言和平臺的gRPC實現可能不如其他語言和平臺成熟和穩定。

  • 依賴於網路和服務發現:gRPC是基於網路的通訊協議,因此在使用gRPC時需要穩定的網路連線。此外,使用gRPC時需要合適的服務發現機制來管理和排程服務例項,這可能需要額外的配置和維護。

總的來說,儘管gRPC具有許多優點,但在選擇使用它時也需要考慮到其可能存在的一些限制和挑戰。根據具體的應用需求和技術環境,需要綜合評估是否適合採用gRPC作為通訊協議。

三者之間的比較

諸如以上內容所述,現在對這三種API的架構設計和實現方式,都有了一個深入的理解,對他們的特性,優點和缺點也有初步的瞭解。

image

下面,是對三個實現方案的一些關鍵特性的一個綜合對比如下:

image

最後

RESTful、GraphQL和gRPC是三種常見的API架構設計和實現模式,它們在設計理念、資料傳輸方式和使用場景上都存在這一定的差異:

  • RESTful是基於HTTP協議的傳統API架構,使用簡單、易於理解,適用於傳統的API開發和資料互動場景。

  • GraphQL是一種靈活的資料查詢語言和API查詢協議,客戶端可以靈活地指定需要的資料,並避免了"過度獲取"的問題,適用於需要動態資料獲取和靈活資料查詢的場景。

  • gRPC是一種高效能的跨語言的遠端過程呼叫協議,使用基於二進位制的通訊協議和強型別介面定義,適用於分散式系統、微服務架構和實時通訊等場景。

我們在做API實現方案的選型時,要結合具體的應用需求、開發團隊的技術能力和技術棧,以及可擴充套件性等實際需求,來選擇適合的方案。要記住的至關重要的一點是:最新的、最流行的不一定是最好的選擇。

另外,無論選擇哪種架構和協議,重要的是理解其特點、原則和使用方式,並根據具體情況進行合理的設計和最佳化,以提供高效、可擴充套件和可靠的API服務。

相關文章