Go Opaque API 移行
Opaque API は、Go プログラミング言語用の Protocol Buffers 実装の最新バージョンです。古いバージョンは Open Struct API と呼ばれています。入門については、Go Protobuf: Releasing the Opaque API のブログ記事を参照してください。
Opaque API への移行は、Protobuf Editions 機能の api_level
オプションをいずれかの可能な値に設定することにより、proto メッセージごとまたは .proto
ファイルごとに行われます。
API_OPEN
は Open Struct API を選択します。これは 2024 年 12 月以前の唯一の API でした。API_HYBRID
は Open と Opaque の間のステップです。Hybrid API にはアクセサメソッドも含まれています(コードを更新できます)が、struct フィールドは以前と同様にエクスポートされます。パフォーマンスの違いはありません。この API レベルは移行を支援するだけです。API_OPAQUE
は Opaque API を選択します。
現在、デフォルトは API_OPEN
ですが、今後の Protobuf Edition 2024 ではデフォルトが API_OPAQUE
に変更されます。
Edition 2024 より前に Opaque API を使用するには、次のように api_level
を設定します。
edition = "2023";
package log;
import "google/protobuf/go_features.proto";
option features.(pb.go).api_level = API_OPAQUE;
message LogEntry { … }
既存のファイルの api_level
を API_OPAQUE
に変更する前に、生成された proto コードの既存のすべての使用箇所を更新する必要があります。open2opaque
ツールがこれを支援します。
便宜上、protoc
コマンドラインフラグを使用してデフォルトの API レベルをオーバーライドすることもできます。
protoc […] --go_opt=default_api_level=API_OPAQUE
特定のファイル(すべてのファイルではなく)のデフォルトの API レベルをオーバーライドするには、apilevelM
マッピングフラグを使用します(インポートパスの M
フラグと同様)。
protoc […] --go_opt=apilevelMhello.proto=API_OPAQUE
コマンドラインフラグは、proto2 または proto3 構文をまだ使用している .proto
ファイルでも機能しますが、.proto
ファイル内から API レベルを選択する場合は、最初にそのファイルをエディションに移行する必要があります。
自動移行
既存のプロジェクトを Opaque API に移行することをできるだけ簡単にするように努めています。当社の open2opaque ツールが作業のほとんどを行います!
移行ツールをインストールするには、以下を使用します。
go install google.golang.org/open2opaque@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. Hybrid API に切り替える
open2opaque
ツールを使用して、.proto
ファイルを Hybrid API に切り替えます。
open2opaque setapi -api HYBRID $(find . -name "*.proto")
既存のコードは引き続きビルドされます。Hybrid API は、新しいアクセサメソッドを追加しますが、struct フィールドを表示したままにする 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 つの一般的な例は、struct リテラルで protobuf メッセージを初期化することです。
return &logpb.LogEntry{
BackendServer: proto.String(host),
}
Opaque API では、同等のものは Builder を使用することです。
return logpb.LogEntry_builder{
BackendServer: proto.String(host),
}.Build()
ツールは、利用可能な書き換えをさまざまなレベルに分類します。-levels=red
引数を指定すると、人間によるレビューが必要なものを含め、すべての書き換えが有効になります。次のレベルが利用可能です
- green: 安全な書き換え (高信頼度)。ツールが行うほとんどの変更が含まれます。これらの変更は詳細な確認を必要とせず、人間の監視なしに自動化によって送信することもできます。
- yellow: (妥当な信頼度) これらの書き換えには人間によるレビューが必要です。それらは正しいはずですが、レビューしてください。
- red: 潜在的に危険な書き換え。まれで複雑なパターンを変更します。これらには注意深い人間によるレビューが必要です。たとえば、既存の関数が
*string
パラメーターを受け取る場合、ポインターに書き込むことによってフィールド値を変更することを目的としている場合 (*foo = "value"
)、proto.String(msg.GetFoo())
を使用する一般的な修正は機能しません。
多くのプログラムは、green レベルの変更のみで完全に移行できます。proto メッセージまたはファイルを Opaque API に移行する前に、すべてのレベルのすべての書き換えを完了する必要があります。その時点で、コード内に直接的な struct アクセスは残っていません。
ステップ 3. 移行と検証
移行を完了するには、open2opaque
ツールを使用して、.proto
ファイルを Opaque API に切り替えます。
open2opaque setapi -api OPAQUE $(find . -name "*.proto")
これで、まだ Opaque API に書き換えられていない残りのコードはコンパイルできなくなります。
ユニットテスト、統合テスト、およびその他の検証手順(ある場合)を実行します。
質問や issue はありますか?
まず、Opaque API FAQ を確認してください。それでも質問に答えられない場合や問題が解決しない場合は、質問や issue を報告できる場所はどこですか? を参照してください。