【Buf Schema Registry】サードパーティの.protoファイルはvendoringしなくてもいいんだね!
https://2.bp.blogspot.com/--o5xXRaB24A/Wf6Ih9gGbEI/AAAAAAABH-8/g0x-lkHfqtkCzBQ1tgx3M96_ZAKfwZnDwCLcBGAs/s800/dance_yorokobi_mai_woman.png
(このブログは2023年3月4日に記載し、2023年3月7日に更新しています)
【前提】
protocはリモートリポジトリ(例えばGitHubのリポジトリ)上に存在する.protoファイルをimportすることは2023年3月現在不可能です。課題解決のために必要な.protoファイルをvendoring(サードパーティのパッケージを自身のリポジトリにコピーして管理)することでローカルに存在する.protoファイルをimportするという手があります。
他にも、protodepを活用することで、リモートリポジトリに存在する.protoファイルをTOML形式で管理することができます。必要な.protoファイルのみを管理することができる上に、リモートリポジトリのバージョンを指定することもできるので、Git submoduleなどで対象リポジトリを管理するよりも低コストな管理を実現できます。
しかし、近年ではprotocよりBufを利用してProtocol Buffersを操作することが多くなっており、更にBufを利用すれば上記のようなvendoringをする必要性がなくなります。今回はBufを活用し、サードパーティの.protoファイルを管理する方法について記載します。
【結論】
Buf Schema Registory(以下BSR) とBufによる課題解決を実施します。BSRはBufにて利用可能なプラグインとリポジトリを管理するレジストリです。BSRのチュートリアルではBSRにてアカウントの作成を紹介していますが、リソースのダウンロードにはアカウントの作成は特に必要ないので、今回は割愛します。
例えば、Google APIにて管理されているannotations.protoを利用してみます。
(Bufのインストールが完了していない場合は、$ brew install bufbuild/buf/bufなどを実行してください。)
まず、$ buf mod initを実行して、buf.yamlファイルを用意します。生成されたbuf.yamlファイルのdepsキーにBSR上にあるGoogleAPIのホスト名およびパスを追加します。
code:buf.yaml
version:v1
...
deps:
- buf.build/googleapis/googleapis
次に$ buf mod updateを実行することで、buf.lockファイルを作成します。このロックファイルにより、対象となるリポジトリやバージョンを確定します。今後、$ buf buildや$ buf generate等のBufのコマンドを実行することでdepsキーで指定したモジュールをローカルにキャッシュします。
ここで、下記のような.protoファイルを用意し、annotations.protoをimportします。
code: main.proto
syntax = "proto3";
import "google/api/annotations.proto";
...
この状態で$ buf buildや$ buf generateを実行すれば、依存関係を解決することができます。こうしてみるとvendoringするより簡単ですね。
【注意】
buf.work.yamlにて、.protoファイルを配置しているディレクトリを指定している場合は、そちらを優先してモジュールの解決を実施するので、サードパーティのモジュールを解決してくれません。
vendoringを実施しない場合、bufコマンドを実行するディレクトリから更にディレクトリを分割(vendoring用のvendorディレクトリと自身の資産を管理するapiディレクトリなどに分割)して.protoファイルを管理するメリットが少ないのでbuf.work.yamlは削除したほうがよいかもしれません。
【余談】
Protocol Buffers関連の記事の中にはリモートリポジトリのimportを実施する例題をよく拝見しますが、vendoringや、BSRを活用する必要性があることを知らないと、どんどん時間が溶けていきますので、注意が必要です。