Open8

Go言語とgRPCで学ぶマイクロサービス開発

Junior DeveloperJunior Developer

Protocol Buffersの構成要素

  • インターフェース定義言語(IDL)
  • シリアライズ形式
  • プログラミング言語向けランタイムライブラリ
  • プロとコンパイラにより生成されるコード

Protocol Buffersの特徴

  • シンプルなデータ形式
  • 相互運用性
  • 拡張性
  • バージョン管理
  • データフォーマット
  • 自動生成
Junior DeveloperJunior Developer

基本言語使用

  • protobufのプログラミングガイド
    https://protobuf.dev/programming-guides/

  • 共通項目(バージョン3の場合)

    • ライセンスヘッダ
    • 生成コードの格納先パッケージの指定
    • パッケージの宣言
syntex = "proto3"; // ライセンスヘッダ
option go_package= "/pb"; // 生成コードの格納先パッケージの指定
package proto; // パッケージの宣言
Junior DeveloperJunior Developer

google.golang.org/protobufモジュール

  • 日付や時刻などを扱うにはgoogle.golang.org/protobufモジュールが提供している「Well Known Types」を使用する。

google.golang.org/protobufモジュールの特徴

  • Google が公式に定義している よく使われる共通の Protocol Buffers メッセージ型 のこと。これらは、日常的に使われるデータ型を標準化したもので、再利用性や互換性を高めるために作られている。

導入方法

go get google.golang.org/grpc
Junior DeveloperJunior Developer

Messageとは?

  • 「データの構造(リクエスト・レスポンスの中身)」を定義するもの。
    • gRPCでは、通信でやり取りするリクエストやレスポンスの型 を、message キーワードで定義する。
message HelloRequest {
  string name = 1;
}

message HelloResponse {
  string message = 1;
}

Serviceとは?

  • gRPCが提供するAPI(関数)群の定義にあたるもの。
    • serviceキーワードを使って、リモートで呼び出せる関数(RPCメソッド)を定義する。
      メソッドごとに、引数のMessage型と戻り値のMessage型を指定する。
service Greeter {
  rpc SayHello (HelloRequest) returns (HelloResponse);
}
Junior DeveloperJunior Developer

コードの生成(プラグインのインストール)

  • google.golang.org/protobuf/cmd/protoc-gen-go
    • proto2とproto3両方のバージョンに対応したGoコード生成機能を提供する
  • google.golang.org/grpc/cmd/protoc-gen-go-grpc
    • サービスのGoバインディングを生成する

インストール方法

go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
Junior DeveloperJunior Developer

Goコードの生成

protocを利用してGoコードを生成すると、XXX.pb.goとXXX_grpc.pb.goの2種類のソースコードが生成される。

XXX.pb.go(Message定義)

このファイルには.protoに定義したmessageenumの構造体が入っている。

  • 主な内容
    • メッセージ構造体やenumなどの定義
  • 生成元のプラグイン
    • protoc-gen-go
// .proto
message HelloRequest {
  string name = 1;
}

// .go
type HelloRequest struct {
  Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
  ...
}

XXX_grpc.pb.go(Service定義)

このファイルには.protoに定義したserviceの定義から「gRPCサーバーインターフェース」、「クライアント用スタブ」、「サーバー登録関数」が生成される。

  • 主な内容
    • gRPCサービス定義(インターフェースやクライアント/サーバー)
  • 生成元のプラグイン
    • protoc-gen-go-grpc
// .proto
service Greeter {
  rpc SayHello (HelloRequest) returns (HelloResponse);
}

// .go
// サーバー側が実装すべきインターフェース
type GreeterServer interface {
  SayHello(context.Context, *HelloRequest) (*HelloResponse, error)
}

// サーバー登録用関数
func RegisterGreeterServer(s grpc.ServiceRegistrar, srv GreeterServer) {
  ...
}

// クライアント用構造体
type GreeterClient interface {
  SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloResponse, error)
}
Junior DeveloperJunior Developer

Goコードの生成(エラー対応)

protocコマンド実行時い下記のエラーが出た際の解消方法

エラーログ

protoc --go_out=./ --go-grpc_out=./ proto/*.proto
protoc-gen-go: program not found or is not executable
Please specify a program using absolute path or make sure the program is available in your PATH system variable
--go_out: protoc-gen-go: Plugin failed with status code 1.

解消手順

// ① .zshrcにパスを追加
$ vim ~/.zshrc
// ② .zshrcに下記を追加
export PATH="$PATH:$(go env GOPATH)/bin"
// ③ 設定を反映
source ~/.zshrc