/golang-echo

gRPC echo-server with golang

Primary LanguageShellMIT LicenseMIT

golang-echo

This sample repository is an echo server with gRPC(protobuf) implemented with Golang.

Survey

GolangでgRPCアプリケーションを開発するにあたって必要そうな知識を整理する

gRPC

  • gRPCはGoogle謹製のHTTP/2を利用したRPC(Remote Produce Call)フレームワーク
  • データのシリアライズにはProtocol Buffersを利用する(Protocol Buffers以外も利用可能だがデファクトスタンダード)
  • RPCとしては他にREST-APIなどがあるが,REST-APIのようにパスやメソッドなどを指定する必要がなく注目されている

gRPC概念図 gRPCの全体像(http://www.grpc.io/docs/より転載)

Protocol Buffers

  • Google製のデータをバイナリ形式にシリアライズするためのフォーマット.JSONの代替を目指しているそう
  • クライアント・サーバー間の通信やデータの永続化などに用いる
  • *.protoファイルに IDL(Interactive Data Language) でデータ構造を記述する
  • 様々な言語で対応する(Golang/Java/Python etc...)
  • シリアライズ・デシリアライズするためのコードが自動生成される(protocコマンドでコンパイルする)
  • レポジトリは protocolbuffers/protobuf. 最新バージョンは 3 (proto3)

Protocol Buffers利用フロー図 Protocol Buffers利用フロー(https://www.apps-gcp.com/grpc-go/より転載)

Go Protocol Buffer Message API

  • 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 の差異より転載

Third Party Library

  • 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 のクライアントツールを調べてまとめてみた

How to use

Protocol Buffers: ざっくりとした入門いまさらだけどgRPCに入門したので分かりやすくまとめてみた などに従いつつ,golang製サーバーがprotobufで書かれたスキーマで通信されている様子をみる.

スキーマからstubコードの生成

スキーマ 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の使い方を参照する

生成されたstubコードをサーバコードに埋め込む

生成されたスタブコードは 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/ へブラウザからアクセスする View

試しに,リクエストとして name=John を送信すると… request

レスポンスの messageHello John が返される. response

応用編

スキーマの変更

JSON にしたい

Reference