Go Opaque API への移行
Opaque API は、Go プログラミング言語向けの Protocol Buffers 実装の最新バージョンです。古いバージョンは現在 Open Struct API と呼ばれています。概要については、Go Protobuf: Opaque API のリリースのブログ記事を参照してください。
Opaque API への移行は、プロトメッセージごと、または .proto ファイルごとに、api_level 機能を可能な値のいずれかに設定することで、段階的に行われます。
API_OPENは Open Struct API を選択します。これは Edition 2023 にバックポートされたため、古いバージョンの Go プラグインでは認識されない場合があります。API_HYBRIDは Open と Opaque の中間のステップです。Hybrid API にはアクセサメソッドも含まれています(そのためコードを更新できます)が、以前と同様に構造体フィールドはエクスポートされます。パフォーマンスの違いはありません。この API レベルは移行に役立つだけです。API_OPAQUEは Opaque API を選択します。これは Edition 2024 以降のデフォルトです。
特定の .proto ファイルのデフォルトをオーバーライドするには、api_level 機能を設定します。
edition = "2024";
package log;
import "google/protobuf/go_features.proto";
option features.(pb.go).api_level = API_OPEN;
message LogEntry { … }
既存のファイルに対して api_level を API_OPAQUE に変更する前に、生成されたプロトコードの既存のすべての使用箇所を更新する必要があります。open2opaque ツールがこれを支援します。
便宜上、protocコマンドラインフラグでデフォルトのAPIレベルをオーバーライドすることもできます。
protoc […] --go_opt=default_api_level=API_OPEN
特定のファイル(すべてのファイルではなく)のデフォルトAPIレベルをオーバーライドするには、apilevelMマッピングフラグを使用します(インポートパスのMフラグと同様)。
protoc […] --go_opt=apilevelMhello.proto=API_OPEN
自動移行
既存のプロジェクトを Opaque API に移行することを可能な限り簡単にすることを目指しています。open2opaque ツールがほとんどの作業を行います!
移行ツールをインストールするには、以下を使用します。
go install google.golang.org/open2opaque@latest
go install golang.org/x/tools/cmd/goimports@latest
注意
自動移行アプローチで問題が発生した場合は、Opaque API: 手動移行ガイドを参照してください。プロジェクトの準備
ビルド環境とプロジェクトが、Protocol Buffers と Go Protobuf の十分に新しいバージョンを使用していることを確認してください。
protobuf コンパイラ (protoc) を protobuf リリースページからバージョン 29.0 以降に更新します。
protobuf コンパイラ Go プラグイン (protoc-gen-go) をバージョン 1.36.0 以降に更新します。
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest各プロジェクトで、
go.modファイルを更新して、バージョン 1.36.0 以降の protobuf モジュールを使用するようにします。go get google.golang.org/protobuf@latest注意
まだgoogle.golang.org/protobufをインポートしていない場合、古いモジュールを使用している可能性があります。google.golang.org/protobufの発表(2020年)を参照し、このページに戻る前にコードを移行してください。
ステップ1. ハイブリッドAPIへの切り替え
open2opaque ツールを使用して、.proto ファイルを Hybrid API に切り替えます。
open2opaque setapi -api HYBRID $(find . -name "*.proto")
次に、プロトコルバッファを再コンパイルします。
既存のコードは引き続きビルドされます。Hybrid API は Open API と Opaque API の間のステップであり、新しいアクセサメソッドを追加しますが、構造体フィールドは可視のままです。
ステップ2. open2opaque rewrite
Go コードを Opaque API を使用するように書き換えるには、open2opaque rewrite コマンドを実行します。
open2opaque rewrite -levels=red github.com/robustirc/robustirc/...
1つ以上のパッケージまたはパターンを指定できます。
例として、次のようなコードがあった場合
logEntry := &logpb.LogEntry{}
if req.IPAddress != nil {
logEntry.IPAddress = redactIP(req.IPAddress)
}
logEntry.BackendServer = proto.String(host)
ツールはそれをアクセサを使用するように書き換えます。
logEntry := &logpb.LogEntry{}
if req.HasIPAddress() {
logEntry.SetIPAddress(redactIP(req.GetIPAddress()))
}
logEntry.SetBackendServer(host)
もう1つの一般的な例は、構造体リテラルでプロトコルバッファメッセージを初期化することです。
return &logpb.LogEntry{
BackendServer: proto.String(host),
}
Opaque API では、同等の機能としてビルダーを使用します。
return logpb.LogEntry_builder{
BackendServer: proto.String(host),
}.Build()
このツールは、利用可能な書き換えを異なるレベルに分類します。-levels=red 引数は、人間によるレビューが必要なものも含め、すべての書き換えを有効にします。以下のレベルが利用可能です。
- green: 安全な書き換え(高い信頼性)。ツールが行う変更のほとんどが含まれます。これらの変更は綿密な確認を必要とせず、人間の監視なしに自動化によって提出することも可能です。
- yellow: (合理的な信頼性)これらの書き換えには人間によるレビューが必要です。これらは正しいはずですが、確認してください。
- red: 潜在的に危険な書き換えで、まれで複雑なパターンを変更します。これらには慎重な人間によるレビューが必要です。たとえば、既存の関数が
*stringパラメータを取る場合、proto.String(msg.GetFoo())を使用する一般的な修正は、その関数がポインタに書き込むことによってフィールド値を変更しようとした場合 (*foo = "value") は機能しません。
多くのプログラムは、green の変更だけで完全に移行できます。プロトメッセージまたはファイルを Opaque API に移行する前に、すべてのレベルのすべての書き換えを完了する必要があります。その時点で、コードには直接的な構造体アクセスが残らなくなります。
ステップ3. 移行と検証
移行を完了するには、open2opaque ツールを使用して、.proto ファイルを Opaque API に切り替えます。
open2opaque setapi -api OPAQUE $(find . -name "*.proto")
これで、まだ Opaque API に書き換えられていない残りのコードはコンパイルされなくなります。
単体テスト、統合テスト、およびその他の検証ステップがあれば実行します。
質問ですか?問題ですか?
まず、Opaque API FAQを確認してください。それでも質問が解決しない場合や問題が解決しない場合は、どこで質問したり問題を報告できますか?を参照してください。