前言:前端
gRPC-Web是一個JavaScript客戶端庫,可使Web應用程序直接與後端gRPC服務進行通訊,而無需HTTP服務器充當中介。nginx
這意味着能夠經過使用.proto文件定義客戶端和服務器端數據類型和服務接口,輕鬆構建真正的端到端gRPC應用程序體系結構。所以,gRPC-Web爲Web開發的整個REST範例提供了一種引人注目的新替代方案。web
基礎:後端
gRPC-Web可以使用.protodefinitions和自動生成客戶端JavaScript在客戶端Web應用程序和後端gRPC服務器之間定義服務「契約」(能夠在Closure編譯器JavaScript或更普遍使用的CommonJS之間進行選擇)。前端框架
能夠放棄開發過程:建立自定義JSON序列化和反序列化邏輯,處理HTTP狀態代碼(可能因REST API而異),內容類型協商等。從更普遍的架構角度來看,gRPC-Web使端到端gRPC成爲可能。下圖說明了這一點:服務器
在左側的gRPC-Web Universe中,客戶端應用程序向GRPC後端服務器說出協議緩衝區,該服務器向其餘gRPC後端服務說出協議緩衝區。架構
在右側的REST Universe中,Web應用程序將HTTP發送到後端REST API服務器,而後該服務器將協議緩衝區稱爲後端服務。須要明確的是,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示例:
一個簡單的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); }
Tip: 能夠在GitHub看rawtodos.proto
可使用該.proto定義使用protoc命令行工具生成CommonJS客戶端代碼:
protoc echo.proto \ --js_out=import_style=commonjs:./output \ --grpc-web_out=import_style=commonjs:./output
Tip: 能夠在GitHub看rawprotoc-gen.sh
如今從後端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()}`); } } });
Tip: 能夠在GitHub託管的rawtodo-service.js
一樣,沒有HTTP代碼或方法,沒有JSON解析,沒有頭協商。聲明瞭數據類型和服務接口,而且gRPC-Web摘錄了全部「硬接線」樣板,提供了一個乾淨且人性化的API(基本上與當前用於gRPC API的Node.js相同的API,剛剛轉移到客戶端)。在後端,gRPC服務器能夠用任何支持gRPC的語言編寫,包括Go,Java,C ++,Ruby,Node.js等等(請參閱官方gRPC文檔中的語言特定文檔)。最後一塊拼圖是服務代理。從一開始,gRPC-Web將支持Envoy做爲默認服務代理,它具備內置的envoy.grpc_web過濾器,只需幾行復制和配置便可應用。
下一步
gRPC-Web正式發佈版本意味着核心構建塊已牢固到位,能夠在生產Web應用程序中使用。可是gRPC-Web還有不少其餘的東西要來。查看官方路線圖,瞭解核心團隊在不久的未來所設想的內容。gRPC-Web還存在着一些問題:
一、前端框架集成 - 經常使用的前端框架如React,Angular和Vue還沒有提供對gRPC-Web的官方支持。但願看到這些框架可以支持它,由於每一個框架都會從gRPC中受益不淺。特定於語言的代理支持 - 從GA版本開始,Envoy是gRPC-Web的默認代理,經過特殊模塊提供支持。但也很樂意看到特定語言的進程內代理的開發。進程內代理消除了對特殊代理(例如Envoy和nginx)的需求,而且使得使用gRPC-Web變得更加容易。
二、特定於語言的代理支持 - 從GA版本開始,Envoy是gRPC-Web的默認代理,經過特殊模塊提供支持。也很樂意看到特定語言的進程內代理的開發。進程內代理消除了對特殊代理(例如Envoy和nginx)的需求,而且使得使用gRPC-Web變得更加容易。
結語
相信gRPC-Web的話題在社區隨着時間推移,會愈來愈活躍。