gRPCのメモ

gRPC

Googleが開発したRPCフレームワークで、基本的にはバックサーバー間通信に使用されることが多い。そのためマイクロサービスなどでよく使用されている。フロントエンドとバックエンドの通信にgRPCを使用したい場合はgRPC-WEBというものを使用する必要がある。

メリット - HTTP/2による高速な通信が可能 - Protocol Buffersによるスキーマファーストの開発。protoファイルというIDLからコードの自動生成が可能。 - 様々なストリーミング方式の通信が可能。 - RestAPIはjson形式で送るため制約がない。gRPCは制約をつけることができる - .proto ファイルにAPI仕様を強制的に明文化できる

RPCとは 〜 歴史的背景から遡る

他のネットワーク上のサーバーにある処理を実行すること

Protocol Buffersとは

  • スキーマ言語(データの構造を定義するための言語)
  • 拡張子は.proto
  • Googleによって開発
  • コンパイルするとインターフェースコードが自動生成されるので、そこから各言語で具象クラスの実装を行う流れで開発する

サービスとメソッドを定義する方法

  • Serviceサービスを定義する
  • ServiceサービスでGetResource呼び出しを定義
  • GetResourceでは、GetResourceRequestメッセージを送信し、GetResourceResponseメッセージを受信する
// Protocol Buffers のバージョンを指定する。省略すると"proto2"と見なされる。
syntax = "proto3";

// import時に名前衝突を避けるための名前空間
package example.sample.1;

// goのコードを生成する場合は必要
option go_package = "example.com/example-package";

// スカラ型以外の型を扱いたい場合は別のファイルからimportしてくる
import "google/protobuf/timestamp.proto";

// サービスの定義
service CouponService {
  rpc GetResource(GetResourceRequest) returns (GetResourceResponse);
}

// メッセージタイプの定義
message CouponResource {
  message Item {

    // シリアライズされたデータではフィールド番号でフィールドを識別するため一意な番号が必要
    int32 id = 1;
    string title = 2;
    google.protobuf.Timestamp release = 3;
    google.protobuf.Duration expiration_limit = 4;

    enum Status {
      RESOURCE_ITEM_STATUS_INVALID = 0;
      RESOURCE_ITEM_STATUS_NORMAL = 1;
      RESOURCE_ITEM_STATUS_MEMBERS_LIMITED = 2;
    }
  }
}

message GetResourceRequest {
  string xxx_request_id = 1;
}

message GetResourceResponse {
  Resource resource = 1;
}

使用方法

以下のコマンドで2つのファイルが自動生成される

$ protoc \
  --go_out=./pb --go_opt=paths=source_relative \
  --go-grpc_out=./pb --go-grpc_opt=paths=source_relative \
  proto/hello.proto

メモ

ネストされたメッセージは重複しても良い
message Outer {
  message MiddleAA {
    message Inner {
      int64 ival = 1;
      bool  booly = 2;
    }
  }
  message MiddleBB {
    message Inner {
      int32 ival = 1;
      bool  booly = 2;
    }
  }
  MiddleBB.Inner inner = 1; // 親メッセージタイプの外で再利用する場合は左のように参照する
}

Protocol Buffersを使用するメリット

  • 厳密な型定義
  • 型を定義することで保管も効くようになる
  • コンパイルすることで各言語用のインターフェースコードが自動生成される

Protocol Buffuersを運用する注意点

  • フィールド番号を変更しないこと
  • Interface定義の都合上、空のリクエストでもパラメーターの入れ物であるstructをリクエスト用のメソッドに渡す必要がある

参考

便利なツール