LoginSignup
3
3

More than 3 years have passed since last update.

痒いところに手が届くprotocol buffersの書き方

Last updated at Posted at 2020-02-09

最近swaggerをprotoに移植する作業をしたので、その過程で調べたことをメモする。
主にprotocol buffersからprotoc-gen-swaggerを使ってswaggerをgenerateする人向け。

descriptionやexampleの文字列を改行する

message IdName {
    option (grpc.gateway.protoc_gen_swagger.options.openapiv2_schema) = {
        json_schema: {
            description: "情報"
                         "テスト"
            required: [
                "id",
                "name"
            ]
        }
        example: { 
            value: "{" 
                        '"id": "1",'
                        '"name": "田中 太郎"'
                    "}"
        }
    };

    int32 id = 1 [(grpc.gateway.protoc_gen_swagger.options.openapiv2_field) = {
        description: "primary key"
    }];

    string name = 2 [(grpc.gateway.protoc_gen_swagger.options.openapiv2_field) = {
        description: "name"
    }];
}

response_bodyのトップレベルをobjectではなく配列にする

{
  "users": [
    {
      "id": "1",
      "name": "test"
    },
    {
      "id": "2",
      "name": "test2"
    }
  ]
}

ではなく、

[
  {
    "id": "1",
    "name": "test"
  },
  {
    "id": "2",
    "name": "test2"
  }
]

にしたい
その場合はresponse_bodyに指定する

message IdNameResponse {
    repeated IdName id_names = 1 [(grpc.gateway.protoc_gen_swagger.options.openapiv2_field) = {
        description: "id name array"
    }];
}

rpc GetIdName(google.protobuf.Empty) returns (user.IdNameResponse) {
    option (google.api.http) = {
        get: "/user/id_name"
        response_body: "id_names"
    };
}

protoc-gen-swaggerを実行する際に、以下のoptionをつける必要がある

allow_repeated_fields_in_body=true

headersの定義

IDはreserveされているものの、未実装
なのでextensionを使って表現する
参考: https://github.com/grpc-ecosystem/grpc-gateway/blob/e1a127c6f7cf2006c77a16dbc0face2a43f2094a/protoc-gen-swagger/options/openapiv2.proto#L85

rpc GetIdName(google.protobuf.Empty) returns (user.IdName) {
    option (google.api.http) = {
        get: "/user/id_name"
    };
    option (grpc.gateway.protoc_gen_swagger.options.openapiv2_operation) = {
    description: "Get user's id and name"
    extensions: {
        key: "x-hoge";
        value {
            string_value: "integer";
        }
    };
}

200以外のresponseの追加

どうやら現状では200を201にするとかはできないらしい
参考: https://github.com/grpc-ecosystem/grpc-gateway/issues/517#issuecomment-536180156
なので、200レスポンスも出てしまうが、201も併記する

rpc CreateIdName(user.IdName) returns (user.IdName) {
    option (google.api.http) = {
        post: "/user/id_name"
        body : "*"
    };
    option (grpc.gateway.protoc_gen_swagger.options.openapiv2_operation) = {
        description: "Create user"
        responses: {
            key: "201";
            value: {
                description: "Successful response"
                schema: {
                    json_schema: {
                        ref: ".user.IdName";
                    }
                }
            }
        };
        responses: {
            key: "401";
            value: {
                description: "Unauthorized"
                schema: {
                    json_schema: {
                        ref: ".error.Error";
                    }
                }
            }
        };
    };
}

defaultの入れ方

int32 id = 1 [(grpc.gateway.protoc_gen_swagger.options.openapiv2_field) = {
    description: "primary key"
    default: "1"
}];

defaultはstringなのでintegerであっても文字列で入れてやる必要がある

その他tips

IDを自動で振り直す

3
3
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
3
3