This sample repository is an echo server with gRPC(protobuf) implemented with Golang.
GolangでgRPCアプリケーションを開発するにあたって必要そうな知識を整理する
- gRPCはGoogle謹製のHTTP/2を利用したRPC(Remote Produce Call)フレームワーク
- データのシリアライズにはProtocol Buffersを利用する(Protocol Buffers以外も利用可能だがデファクトスタンダード)
- RPCとしては他にREST-APIなどがあるが,REST-APIのようにパスやメソッドなどを指定する必要がなく注目されている
gRPCの全体像(http://www.grpc.io/docs/より転載)
- Google製のデータをバイナリ形式にシリアライズするためのフォーマット.JSONの代替を目指しているそう
- クライアント・サーバー間の通信やデータの永続化などに用いる
*.proto
ファイルに IDL(Interactive Data Language) でデータ構造を記述する- 様々な言語で対応する(Golang/Java/Python etc...)
- シリアライズ・デシリアライズするためのコードが自動生成される(
protoc
コマンドでコンパイルする) - レポジトリは protocolbuffers/protobuf. 最新バージョンは 3 (proto3)
Protocol Buffers利用フロー(https://www.apps-gcp.com/grpc-go/より転載)
- Go Protocol Buffer Message APIとはGolang製アプリが Protocol Bufferを利用するためのもの.最近,仕様にAPIの刷新があったことと関連レポジトリが多いので整理
- 2020/3/20 APIv2 がGo公式ブログで発表.これによりGoでもReflectionが使えるようになった.
- APIv2 は後方互換性はないが,APIv1 は今後もずっとサポートを継続するそう
- Protocol Buffer側のレポジトリは golang/protobuf から protocolbuffers/protobuf-go に移行.Protocol Buffersのメッセージやシリアライズに
protoc-gen-go
コマンドを利用 - gPRC側のレポジトリの grpc/grpc-go に新たに
protoc-gen-go-grpc
コマンドができた.gPRCのサーバ/クライアントに用いるインターフェース(スタブコード)を生成ためにこのコマンドを利用 - gRPCを利用したアプリの作成には上記の両方のコマンドが必要
対応表
対象 | APIv1 | APIv2 |
---|---|---|
import のパス | github.com/golang/protobuf | google.golang.org/protobuf |
ソースのリポジトリ | https://github.com/golang/protobuf | https://github.com/protocolbuffers/protobuf-go |
protoc-gen-go | github.com/golang/protobuf/protoc-gen-go | google.golang.org/protobuf/cmd/protoc-gen-go |
gRPCスタブコード生成 | 同上 | google.golang.org/grpc/cmd/protoc-gen-go-grpc |
Protocol Buffers用 Go言語APIの APIv1 と APIv2 の差異より転載
- gogo/protobuf は公式の golang/protobuf を補完する非公式のライブラリ.2021/02現在APIv1にのみ対応.(Reflectionに対応していたがAPIv2で公式に対応されたので利用するメリットはない?)
- grpc-ecosystem/go-grpc-middleware はinterceptorを集めたライブラリ.リクエストパラメータに依存しない共通処理(具体的には認証・ログ・バリデーション・監視など)をintercept(傍受,途中で捕える)できる機構がgRPCのinterceptor
- gRPC command line tool はコマンドラインでgRPCを呼び出すためのコマンド(gRPCはcurl等で手軽に動作確認できないため)
- gRPCurl は同上のCLIツール.4.5kスター(2021/02時点).他にもgRPCのクライアントCLIツールはたくさんある模様. gRPC の CUI のクライアントツールを調べてまとめてみた
Protocol Buffers: ざっくりとした入門 や いまさらだけどgRPCに入門したので分かりやすくまとめてみた などに従いつつ,golang製サーバーがprotobufで書かれたスキーマで通信されている様子をみる.
スキーマ helloworld.proto
を元に,protoc
でgolang向けのstubコードを生成する.
golang向けのstubコードの生成にはプラグイン(google.golang.org/protobuf/cmd/protoc-gen-go)が必要になるが,protocコマンドとそのプラグインがセットになった仮想環境ghcr.io/tk42/protoc
イメージを使って,そのあたりの工程はスキップする.(便利!)
docker compose run protoc
.proto
では生成されるパッケージの指定go_packages
を指定しなければエラーになる.
protocの引数は--go_grpc_out
を含めることを忘れないようにする.これがないとスタブコードにRegisterXXX
が作成されない.
その他はprotocの使い方を参照する
生成されたスタブコードは proto/autogen/helloworld.pb.go
に配置される.
このコードをserver/main.go
に埋め込み,呼び出すようにする.
サーバ側は通常のgolangコンテナでビルド,実行を行う.
gRPC版のcurl
ともいうべきCLIツール grpcurl
のWebフロントラッパー fullstorydev/grpcurl を仮想化されたイメージ wongnai/grpcui を利用して,ブラウザ経由でサーバとgRPC通信する.
docker compose up server client
そして,http://0.0.0.0:5000/ へブラウザからアクセスする