理系学生日記

おまえはいつまで学生気分なのか

gRPC の proto を生で読むのに人生疲れたので protoc-gen-doc で gRPC の API 仕様を HTML 化して読む

gRPC を使いはじめ、.proto に多くの RPC を定義してきました。そうすると、

  • 様々な Req/Res が階層構造を持つ message として定義されるようになる
  • その message が様々な RPC で横断的に使われるようになる

ということが当然のように起こります。

ぼくは従来、他の人にも「いやいや、.proto 見れば RPC の I/F 仕様なんてわかるでしょ」とか宣ってきた過去があります。 しかし、10 とか 20 とかの rpc が定義されてくるとなかなかそういうわけにはいかない。 チームの方からも RPC の I/F 仕様がわかりづらいので、なんとかしてくれ、みたいな要望も来るようになりました。

protoc-gen-doc の導入

そこで導入したのが、protoc-gen-doc です。

protoc-gen-doc は protoc のプラグインとして作成されたもので、.proto の情報を元にして I/F 仕様を markdown や html 等で出力してくれます。 百聞は一見にしかずなので、以下のサンプルを見ると、どういう形で API 仕様が出力されるかが分かると思います。

各フィールドや Req/Res に Description が付加されていますが、これは .proto 上のコメントを出力してくれています。 つまり、.proto のコメントを充実させれば、RPC の I/F 仕様としても充実するわけで、スマートで良いですね。

protoc のプラグインとして作られているが故にその導入も簡単で、例えば以下のようにしてやれば簡単に HTML 出力が可能です。

# インストール
$ go get -u github.com/pseudomuto/protoc-gen-doc/cmd/protoc-gen-doc
# html 出力
$ protoc --doc_out=./doc --doc_opt=html,hoge.html hoge.proto

protoc のプラグインについては 公式 にわずかに記述が存在するのですが、 Qiita 上の以下の記事が一番わかりやすいと思います。

protoc が .proto の解析結果を CodeGeneratorRequest として標準入力経由で渡してくれます。 プラグイン側ではそれを解析し処理をして、その結果を CodeGeneratorResponse として標準出力に出力するというモデルになります。

導入した結果

導入した結果ですが、見違えて I/F 仕様が分かりやすくなりました。

.proto だけを見る場合、ネストした message などは基本的に文字列検索して探さざるを得ず、1 ファイルの中で行き来して効率を下げていました。

しかし、proto-gen-doc を導入するとそれらが HTML リンクとして辿れるようになり、行ったり来たりはブラウザの機能でできるようになります。

さらに、HTML/CSS の表現力はさすがに .proto というテキストファイルを凌駕していて、見た目にもずいぶんわかりやすくなりました。 (proto-gen-doc で生成される HTML/Markdown 等は、go template を使って拡張も可能です)

というわけで、ちょっと規模のある gRPC サーバとかを作ろうと思ったら、本当に proto-gen-doc はお勧めです。