[note] gRPC Golang 筆記
- Basics Tutorial @ gRPC.io
- Sample Code: gRPC-go-sandbox @ pjchender github
- grpc/grpc-go
- routeguide/server @ Github
- routeguide/client @ Github
TL;DR
注意
此筆記使用的是較舊的 gRPC-Go 工作流程,包含已過時的 github.com/golang/protobuf 套件與 --go_out=plugins=grpc 方式。現代做法(Go 1.17+)應改用 google.golang.org/protobuf 與獨立的 protoc-gen-go-grpc 插件,並使用 go install 安裝 CLI 工具。請參考最新的 gRPC Getting Started 筆記。
當 protocol buffer 是要在 gRPC 使用的話,需要使用到 grpc-go 的套件:
$ go get -u google.golang.org/grpc
或者:
$ go get -u github.com/golang/protobuf/{proto,protoc-gen-go}
$ go get -u google.golang.org/grpc
如此就可以使用 --go_out=plugins=grpc 的方式,透過 protocol buffer 產生支援 gRPC 的 .pb.go 檔:
# 進入到 proto 檔案的資料夾中,輸入
$ protoc *.proto --go_out=plugins=grpc:. --go_opt=paths=source_relative
前端 gRPC 測試工具
- bloomrpc @ GitHub(已停止維護)
$ brew install --cask bloomrpc
Go Generated Code
安裝
- proto-lens: installing protoc @ google/github
- 其他作業系統的安裝方式可參考 Project Setup (Golang + VSCode + Protoc) @ Udemy
要根據 proto buffer 產生新的 .proto.go 檔:
compiler
# 安裝 compiler,安裝完後就會有 protoc CLI 工具
$ brew install protobuf
$ protoc --version # Ensure compiler version is 3+
protobuf
protoc-gen-go 可以將 Protocol Buffer 編譯成 go 的檔案:
# 安裝 protoc-gen-go 後可以將 protocol buffer 編譯成 Golang 可使用的檔案
# Go 1.17+ 應使用 go install 安裝 CLI 工具
$ go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
gRPC-go
當 protocol buffer 是要搭配使用 gRPC 時,需要安裝 gRPC-go 的套件:
# 安裝 grpc-go 後,可以在 Golang 中使用 gRPC
$ go get -u google.golang.org/grpc
如此才使用--go_out=plugins=grpc 的方式,透過 protocol buffer 產生支援 gRPC 的 .pb.go 檔。
Compile 成 pb.go 檔
# 進入到 proto 檔案的資料夾中,輸入
$ protoc *.proto --go_out=plugins=grpc:. --go_opt=paths=source_relative
# 或者在專案的根目錄輸入
# --go_opt=paths=source_relative 表示要用相對路徑產 生檔案
$ protoc -I <src_proto_folder> --go_out=plugins=grpc:<dist_directory> --go_opt=paths=source_relative <src_proto_file_path>
$ protoc -I proto/jubox --go_out=plugins=grpc:proto/jubox --go_opt=paths=source_relative proto/jubox/jubox.proto
# 產生編譯檔(產生一般的 .pb.go 檔,但沒有使用 gRPC plugin
$ protoc -I=$SRC_DIR --go_out=$DST_DIR $SRC_DIR/addressbook.proto # 預設根據 go_package 路徑
# 產生 proto 檔,預設將根據 proto 中的 go_package 路徑
$ protoc -I=$SRC_DIR --go_out=$DST_DIR $SRC_DIR/addressbook.proto
# 另一種寫法會 build 出兩隻檔案,一支是 proto buffer(foobar.pb.go),一支是 gRPC 用的檔案(foobar_grpc.pb.go)
$ protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative {proto_filename}.proto
- 使用
--go_out會產生由.proto編譯後的.go檔,原本的foo.proto會變成foo.pb.go - 在
.proto檔案中,要包含go_package的屬性,當中要指定包含 generated code 中程式碼的 full Go import path
option go_package = "example.com/foo/bar";
-
output 資料夾的檔案會根據
go_package的屬性和 compiler flags 有不同- 預設情況下,output 檔案會被放在與
go_package屬性相同的資料夾名稱內 - 透過
--go_opt=paths=source_relative則可以修改 output file 產生的位址
- 預設情況下,output 檔案會被放在與
-
如果需要打包成給 gRPC 使用的 GO 檔,需要使用
--go_out=plugins=grpc:<path>:
simple RPC(Unary API)
範例程式碼:
- Create Simple RPC Example @ Github
- simple RPC example(client) @ Github
1. 使用 proto 定義 service
在 proto 檔中定義 Service:
service RouteGuide {
// A simple RPC
// A feature with an empty name is returned if there's no feature at the given position
rpc GetFeature(Point) returns (Feature) {}
}