LoginSignup
65
53

More than 3 years have passed since last update.

gRPCで使う.protoファイルの書き方まとめ

Posted at
  • gRPCでは、Protocol Buffersのフォーマットでシリアライズしてデータのやり取りを行う。
  • .protoファイルにてスキーマ定義を行い、ツールを使ってコード生成ができる。そのため、クライアント・サーバーそれぞれでこの.protoファイルを共有できれば、仕様のズレなく開発をすすめることが可能。
  • この記事では、.protoファイルの文法をざっとまとめてみる

サンプル全体

// バージョン定義
syntax = "proto3";

// パッケージ定義
package sample;

// import
import "google/protobuf/timestamp.proto";
import "google/protobuf/duration.proto";

// サービスとRPCメソッド定義
service SampleService {
    rpc Sample (SampleRequest) returns (SampleResponse);

    // サーバーストリーミングRPC
    rpc SampleServerStreamMethod (SampleRequest) returns (stream SampleResponse);

    // クライアントストリーミングRPC
    rpc SampleClientStreamMethod (stream SampleRequest) returns (SampleResponse)

    // 双方向ストリーミングRPC
    rpc SampleBidirectionalMethod (stream SampleRequest) returns (stream SampleResponse)
}

message SampleRequest {
    string name = 1;
}

message SampleResponse {
    Sample sample = 1;
}


// メッセージ型
// 右の数字は「タグナンバー」
message Sample {
    // スカラー型
    // 数値、文字列、真偽値、バイト配列がある
    int32 id = 1;
    string name = 2;
    bool isBool = 3;

    // deprecated 廃止予定かつ非推奨であるフィールドを明示する
    string duplicated_field = 4 [deprecated = true]

    // reserved識別子 廃盤にしたタグナンバー
    reserved 7, 8, 10 to 12;

    // リスト(配列)
    // 多次元配列は定義できない
    repeated SampleList sample_list = 5;

    // マップ(連想配列)
    map<string, string> sample_map = 6;

    // 複数の中からどれかひとつ
    oneof message {
        string one = 1;
        string other = 2;
    }

    // Well Known Types
    google.protobuf.Duration sample_duration = 9;
    google.protobuf.Timestamp create_time = 13;

    // 列挙型
    enum SampleEnum {
        UNKNOWN = 0;
        TEST1 = 1;
        TEST2 = 2;
        TEST3 = 3;
    }

}

バージョンの定義

syntax = "proto3";

パッケージの定義

  • 他の.protoファイルで定義したメッセージを使うときなどに、名前の衝突を避けるためにパッケージ名を設定できる
package sample;

import

  • 他の.protoファイルで定義したメッセージ型を使いたい場合に使う
  • ここではGoogleがつくった.protoファイルをimportしている
import "google/protobuf/timestamp.proto";
import "google/protobuf/duration.proto";

サービスとRPCメソッド

  • APIの定義本体
  • SampleServiceというサービスを定義
  • SampleRequestを引数に取り、SampleResponseを返すSampleというメソッドを定義している
  • ストリーミングにしたい場合は引数、戻り値にstreamをつける
  • 単方向ストリーミング
    • サーバーストリーミングRPC(戻り値にstreamを設定)
      • サーバー側が複数のレスポンスを非同期で返す
    • クライアントストリーミングRPC(引数にstreamを設定)
      • クライアント側から複数のリクエストを非同期で送り、サーバー側は1つのレスポンスを返す
  • 双方向ストリーミング
    • 引数、戻り値の両方にstreamをつける
service SampleService {
    rpc Sample (SampleRequest) returns (SampleResponse);

    // サーバーストリーミングRPC
    rpc SampleServerStreamMethod (SampleRequest) returns (stream SampleResponse);

    // クライアントストリーミングRPC
    rpc SampleClientStreamMethod (stream SampleRequest) returns (SampleResponse);

    // 双方向ストリーミングRPC
    rpc SampleBidirectionalMethod (stream SampleRequest) returns (stream SampleResponse);
}

スカラー型

データ型 デフォルト値
string 空文字
bytes 空配列
bool false
数値 0
enum 最初に定義された値。必ず0にする
メッセージ型 実装依存
repeated 空配列

メッセージ型

  • 複数のフィールドを持った型
  • タグナンバー
    • フィールドの右側の数字。
    • 同一メッセージ内で一意にしなければならない
    • reserved識別子
      • フィールド削除などで廃盤にしたタグナンバーを記載する
    • deprecatedオプション
      • 廃止予定かつ非推奨のフィールドを明示する
message Sample {
    // スカラー型
    // 数値、文字列、真偽値、バイト配列がある
    int32 id = 1;
    string name = 2;
    bool isBool = 3;

    // deprecated 廃止予定かつ非推奨であるフィールドを明示する
    string duplicated_field = 4 [deprecated = true]

    // reserved識別子 廃盤にしたタグナンバー
    reserved 7, 8, 10 to 12;

  // 〜 中略 〜
}

リスト(配列)

  • 型の前にrepeatedをつけることで配列を定義できる
  • スカラー型・メッセージ型ともに使用可能
  • 多次元配列は定義できない
    // リスト(配列)
    // 多次元配列は定義できない
    repeated SampleList sample_list = 5;

マップ(連想配列)

  • キーには整数値、文字列、真偽値のみ使える
  • mapは配列にできない
    map<string, string> sample_map = 6;

列挙型

  • 型の前にenumをつけることで列挙型を定義できる
    // 列挙型
    enum SampleEnum {
        UNKNOWN = 0;
        TEST1 = 1;
        TEST2 = 2;
        TEST3 = 3;
    }

oneof

  • oneofをつけることで、複数のものから1つという定義ができる
  • ここではoneotherを返すメッセージ型になる
    oneof message {
        string one = 1;
        string other = 2;
    }

Well Known Types

  • Googleが定義したメッセージ型
  • 日時・期間や、戻り値を返さないことを表すものなどがある
    google.protobuf.Duration sample_duration = 9;
    google.protobuf.Timestamp create_time = 13;

コードの生成

  • 上記で定義した.protoファイルをもとに、クライアント・サーバーの両サイドで各言語用のprotocコマンドを使ってボイラープレートコードを生成する

参考

65
53
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
65
53