1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Protocol Buffersの定義をMarkdownで出力するためのカスタムテンプレートを作った

Last updated at Posted at 2021-04-05

モチベーション

現在のプロジェクトではProtocol Buffersの定義ファイルは画面が必要としている関心事ごとに
サービスが分割されており1サービスが1つのpackageに紐づくよう設計されています。
そのためProtocol Buffersは以下のような複数ファイル構成になっています。

srcproto
  └ app
    ├ user
    │ └ user.proto
    ├ comment
    │ └ comment.proto
    └ search
      └ search.proto

リクエストパラメータのvalidationもProtocol Buffers上で定義されており、現在mwitkow/go-proto-validatorsenvoyproxy/protoc-gen-validate が使用されています。

このvalidationの閾値をProtocol Buffersを設計しているバックエンダー以外へ連携する際に
そのままprotoファイルを見せても分かりにくいので、1つのMarkdownにまとめてドキュメント化しようというのが今回やりたかったことです。

Protocol Buffersをドキュメント化する事自体はpseudomuto/protoc-gen-doc というlibraryで既に提供されているためこちらを使用します。
しかし、デフォルトの状態で出力されるMarkdownファイルはファイル毎に分割されてしまう上にそもそもvalidationの設定が出力されないためカスタムテンプレートを用意することにしました。

作成したもの

以下のテンプレートを作成しました。
https://gist.github.com/tomtwinkle/074bfc9cd4db53b58bb4ff368157f3ed

使い方としては

srcproto
│ └ app
│   ├ user
│   │ └ user.proto
│   ├ comment
│   │ └ comment.proto
│   └ search
│     └ search.protocustom_markdown.tmpl # <--- custom template

のように配置し --doc_out にドキュメントの出力先、--doc_opt にテンプレートの設定とファイル名を追加して protoc を実行します。

cd src
protoc -I . -I <validatorのパス> --proto_path=proto --doc_out=../docs --doc_opt=custom_markdown.tmpl,doc.md ./proto/app/**/*.proto
srcproto
│ └ app
│   ├ user
│   │ └ user.proto
│   ├ comment
│   │ └ comment.proto
│   └ search
│     └ search.protocustom_markdown.tmpl # <--- custom template
docsdoc.md # <--- generate markdown document

コードジェネレートとセットで行うことも出来ます。
例えばgolangとgrpc-webのコードジェネレートとセットで行う場合は以下のようになります。

protoc -I . -I <validatorのパス> --proto_path=proto --doc_out=../docs --doc_opt=custom_markdown.tmpl,doc.md --proto_path=proto --go_out="plugins=grpc:../go" --validate_out="lang=go:../go" --grpc-web_out=import_style=commonjs+dts,mode=grpcwebtext:../web --js_out=import_style=commonjs:../web ./proto/app/**/*.proto

おまけ:validatorのパスを書きたくない

Protocol Buffersの定義をMarkdownで出力するネタとは全然関係ないですが
validatorをProtocol Buffersで定義する場合どうしてもvalidator自身のproto fileのパスをprotocに読ませる必要があるため

GO111MODULE=off go get github.com/envoyproxy/protoc-gen-validate
protoc -I $GOPATH/src/github.com/envoyproxy/protoc-gen-validate

みたいな手順を開発環境の構築手順に加えてあげる必要が出てきてしまいます。
go getしてくるpackageは開発者毎に異なる可能性があり環境差分が生まれる原因ともなります。

解決するためにはProtocol Buffersのソース内にvalidatorのpackage名のディレクトリを掘りvalidator自体のprotoファイルをライセンスファイルとセットで置いてあげるのが良さそうです。(Apache License 2.0なので)
protoファイルを取り込む場合はそれぞれのvalidatorのライセンスをよく確認してください。

srcproto
│ ├ app
│ │ ├ user
│ │ │ └ user.proto
│ │ ├ comment
│ │ │ └ comment.proto
│ │ └ search
│ │   └ search.proto
│ └ github.com # <------ validator proto files
│   ├ envoyproxy
│   │ └ protoc-gen-validate
│   │   ├ validate
│   │   │ └ validate.proto
│   │   ├ LICENSE
│   │   └ NOTICE
│   └ mwitkow
│     └ go-proto-validators
│       ├ validator.proto
│       └ LICENSE.txtcustom_markdown.tmpl
docsdoc.md
go
web

使うvalidatorが envoyproxy/protoc-gen-validate だけで良いなら mwitkow/go-proto-validators のディレクトリは不要です。逆もまた然り。

validatorを使用したいprotoファイル内では以下のようにimportします。

import "github.com/envoyproxy/protoc-gen-validate/validate/validate.proto";

package名と同じディレクトリを作成することにより

Before
protoc -I . -I <validatorのパス> <build options> ./proto/app/**/*.proto

と参照パスをオプションで指定する必要があったものが

After
protoc <build options> ./proto/app/**/*.proto

だけでbuild出来るようになります。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?