gRPC-Web發佈,REST又要被幹掉了?

gRPC-Web發佈,REST又要被幹掉了?

凌亂的桌子和與 Web 的設計理念說明

今天,雲原生計算基金會(CNCF)正式發佈 GA 版本的 gRPC-Web,這是一個 JavaScript 客戶端庫,使 Web 應用程序能夠直接與後端 gRPC 服務通信,不需要 HTTP 服務器充當中介。

這意味著你現在可以通過.proto 文件來定義客戶端和服務器端數據類型和服務接口,輕鬆構建真正的端到端 gRPC 應用程序架構。gRPC-Web 為 Web 開發提供了 REST 之外的另一個選擇。

gRPC-Web 簡介

gRPC-Web 讓你能夠使用.proto 來定義客戶端 Web 應用程序和後端 gRPC 服務器之間的服務“契約”,並自動生成客戶端 JavaScript(你可以選擇 Closure 編譯器或使用更為廣泛的 CommonJS)。

你可以不用再為這些事情操心:創建自定義 JSON 序列化和反序列化邏輯、處理 HTTP 狀態代碼(可能因REST API 而異)、Content-Type 協商等。

從更廣泛的架構角度來看,gRPC-Web 讓端到端的 gRPC 成為可能。如下圖所示:

gRPC-Web發佈,REST又要被幹掉了?


在左側,一個客戶端應用程序通過 Protocol Buffers 與一個 gRPC 後端服務器通信,然後這個服務器也通過 Protocol Buffers 與其他的 gRPC 後端服務器通信。在右側,Web 應用程序通過 HTTP 與後端 REST API 服務器通信,然後這個服務器又通過 Protocol Buffers 與其他後端服務通信。

需要明確指出的是,右側的 REST 應用程序本身沒有任何問題。已經有大量非常成功的應用程序是基於 REST API 服務器而構建的,這些服務器使用非 HTTP 協議與後端服務進行通信。但如果這些應用程序的開發過程只圍繞一個協議和一組.proto 接口(以及一組服務契約)進行,那麼就可以節省無數個小時的時間以及避免那些令人頭疼的問題。

gRPC-Web 的好處不僅僅體現在“技術”方面,還體現在對組織的影響上。圖中的亮橙色線不僅僅是一個協議——它代表的是獨立的工作和認知負荷來源,而現在,你完全可以把它變成亮綠色。

gRPC-Web 的優勢

隨著時間的推移,gRPC-Web 將提供更廣泛的特性集。目前,我可以看到的是:

  • 端到端 gRPC——如上所述,有了 gRPC-Web,你就可以正式從技術棧中移除 REST 組件,並用 gRPC 來替換,從而可以使用 Protocol Buffers 來創建整個 RPC 管道。想象一下這樣的場景:一個客戶端請求被轉發到 HTTP 服務器上,HTTP 服務器與後端的 5 個 gRPC 服務進行交互。你很可能需要花費很多時間來構建 HTTP 交互層,因為你需要構建整個管道的其餘部分。
  • 前端和後端團隊之間更緊密的協作——回看上面的圖表,使用 Protocol Buffers 定義整個 RPC 管道後,你就不再需要將“微服務團隊”與“客戶端團隊”捆綁在一起。客戶端與後端之間的交互只是多了一個 gRPC 層。
  • 輕鬆生成客戶端庫——使用 gRPC-Web 之後,與“外部”世界交互的服務器變成了 gRPC 服務器而不是 HTTP 服務器,這意味著所有的客戶端庫都可以是 gRPC 庫。需要 Ruby、Python、Java 和其他 4 種語言的客戶端庫嗎?你不再需要為所有這些語言編寫 HTTP 客戶端了。

gRPC-Web 示例

上面介紹了 gRPC-Web 在大規模應用中的一些優勢。現在讓我們通過一個例子來說明:一個簡單的 TODO 應用程序。在 gRPC-Web 中,你可以從一個簡單的 todos.proto 定義開始,如下所示:

syntax = “proto3”;
package todos;
message Todo {
string content = 1;
bool finished = 2;
}
message GetTodoRequest {
int32 id = 1;
}
service TodoService {
rpc GetTodoById (GetTodoRequest) returns (Todo);
}

你可以使用這個.proto 定義和 protoc 命令行工具生成 CommonJS 客戶端代碼:

protoc echo.proto \
--js_out=import_style=commonjs:./output \
--grpc-web_out=import_style=commonjs:./output

然後從後端 gRPC 服務器獲取 TODO 列表:

const {GetTodoRequest} = require(‘./todos_pb.js’);
const {TodoServiceClient} = require(‘./todos_grpc_web_pb.js’);
const todoService = new proto.todos.TodoServiceClient(‘http://localhost:8080’);
const todoId = 1234;
var getTodoRequest = new proto.todos.GetTodoRequest();
getTodoRequest.setId(todoId);
var metadata = {};
var getTodo = todoService.getTodoById(getTodoRequest, metadata, (err, response) => {
if (err) {
console.log(err);
} else {
const todo = response.todo();
if (todo == null) {
console.log(`A TODO with the ID ${todoId} wasn’t found`);
} else {
console.log(`Fetched TODO with ID ${todoId}: ${todo.content()}`);
}
}
});

這裡沒有 HTTP 代碼或方法,沒有 JSON 解析,沒有頭部信息協商。你聲明瞭數據類型和服務接口,gRPC-Web 抽離了所有的樣板代碼,留給你的是一組乾淨且人性化的 API。

在後端,gRPC 服務器可以使用任何支持 gRPC 的語言編寫,包括 Go、Java、C++、Ruby、Node.js 等等(請參閱官方 gRPC 文檔中的與開發語言相關的文檔 https://grpc.io/docs/)。

最後一個關鍵組件是服務代理。從一開始,gRPC-Web 支持將 Envoy 作為默認服務代理,它提供了內置的 envoy.grpc_web 過濾器,只需幾行配置即可。更多信息將在 Envoy 博客上(https://blog.envoyproxy.io/)詳細說明。

下一步

GA 版本的發佈意味著核心構建塊已經就緒,可以用在生產環境中。但 gRPC-Web 還將帶來很多其他的東西。

可以查看官方的開發路線圖(https://github.com/grpc/grpc-web/blob/master/ROADMAP.md),以便了解核心團隊所設想的未來。

如果你有興趣為 gRPC-Web 做出貢獻,核心團隊希望社區能夠為以下事項提供幫助:

  • 前端框架集成——常用的前端框架(如 React、Angular 和 Vue)尚未正式支持 gRPC-Web。我們希望看到這些框架能夠支持它,因為每個框架都將從 gRPC 中受益匪淺。
  • 特定於語言的代理支持——截止 GA 版本,Envoy 是 gRPC-Web 的默認代理,通過一個特殊的模塊提供支持。我們也很樂意看到使用其他特定語言開發進程內代理。進程內代理移除了對特殊代理的依賴——例如 Envoy 和 nginx——並且可以讓 gRPC-Web 的使用變得更加容易。

商業用途請與作者聯繫!


分享到:


相關文章: