こんにちは、ティアフォーで認証認可基盤を開発している澤田です。最近取り入れたProtobufで、素晴らしいREST APIの開発体験をしたのでご紹介します。
マイクロサービス間連携のAPI開発において、以下の条件を満たすやり方を探していました。
Go言語で開発する場合はgo-swaggerでも実現できますが、本記事では、Protobufで実現できるgRPC Gatewayとprotoc-gen-validate (PGV)を使った方法をご紹介します。
https://github.com/grpc-ecosystem/grpc-gateway
gRPC GatewayはProtobufの定義からREST APIのプロキシを生成してくれるプラグインです。gRPCサーバの前段に置くことで、REST APIのインターフェイスを提供することができます。
gRPC Server の前段に gRPC Gateway を置くパターン
単にREST APIを開発する場合は、gRPCサーバは不要なので、gRPC Gatewayにサービスの実装を登録することができます。
gRPC Server を置かずに gRPC Gateway だけのパターン
以下の例のように、Protobufから生成されたRegisterXXXHandlerServerを利用すれば、Gatewayにサービスの実装を登録することができます。
ご参考までにProtobufの定義も載せておきます。message定義の中で必須のフィールドを指定しておくと、swaggerとして吐き出されるときにrequiredとして表現されます。設定を忘れやすいところではありますが、Goの場合は生成したopenapi.yamlからAPI Clientを自動生成し、インテグレーションテストの仕様により必須でないフィールドはポインタになるため、設定を忘れていたことに気づけます。
ちなみに、生成されるドキュメントはOpenAPI v2なので、v3の形式で欲しい場合は以下のようなツールを使ってさらに変換をかける必要があります。
https://github.com/Mermade/oas-kit/blob/main/packages/swagger2openapi/README.md
また、openapi.yamlからAPI Clientの自動生成はoapi-codegenを利用しています。
https://github.com/deepmap/oapi-codegen
https://github.com/envoyproxy/Protobufc-gen-validate
ProtobufからgRPCのメッセージバリデーションを生成してくれるプラグインです。アノテーションでバリデーションルールを表現できます。
gRPCサーバがある場合は、Interceptorでバリデーションできますが、サービスを登録したgRPC Gatewayで使う場合はInterceptorの出番がなく、またHTTPのMiddlewareレイヤではバリデータが使用できません。そのため、Handler内で request.Validate() メソッドを呼ぶ必要があります。
愚直にHandlerの処理でバリデーションメソッドを呼んでもいいのですが、私のチームでは、専用のレイヤでバリデーションするようにしました。コード量は増えてしまいますが、バリデーションの実装忘れは発生しにくいと思います。
REST APIに限った話ではないのでテーマから少し脱線してしまいますが、開発体験を良くしてくれたBufについても簡単にご紹介させてください。
BufはProtobufの依存管理やprotocで実行していたコマンドをいい感じにまとめてくれるツールです。これを使うことで、 依存管理の悩みから開放され、protocコマンドで長たらしく書いていたものをbuf generateとシンプルにまとめることができます。
https://docs.buf.build/introduction
protoディレクトリをprotoファイルの置き場とした場合、以下のような構成になります。
RepositoryRoot
├── buf.gen.yaml // protoc コマンドの引数ここで定義する
├── buf.work.yaml // workspaceを指定。この場合は proto ディレクトリを指定する
└── proto
├── buf.lock // buf.yaml を作成後、 buf mod update コマンドで自動生成される
├── buf.yaml // .proto ファイルで使用されている依存の定義
└── example
└── echo.proto
BufはBSRというProtobuf(Repository)とプラグインのレジストリを提供しています。
Protobufを提供しているRepositoryは充実していますが、プラグインはBSRに登録されていないことがあります。例えば、protoc-gen-validateのRepositoryはありますが、2022年1月現在プラグインは提供されていないので、プラグインが実行可能なDockerfileを自分で用意、BSRに登録し、使えるようにする必要があります。
今回は、Protobufを使ってREST APIを開発する方法と、ProtobufのツールであるBufについてご紹介しました。バリデーションまでできるスキーマ駆動開発の方法はかなり少ないと感じており、今後しばらくは有力な選択肢の一つになるのではないかと思っています。
オープンソースのソフトウェアを一緒に開発していきませんか?
ティアフォーでは、「自動運転の民主化」というビジョンに共感を持ち、自らそれを実現する意欲に満ち溢れた新しい仲間を募集しています。
Media Contact
Share the post
LinkedIn | Twitter | Facebook | Instagram
More
Autoware—Github | The Autoware Foundation