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 の中間のステップです。ハイブリッド API はアクセサーメソッドも含まれるため(コードを更新できます)、以前と同様に構造体フィールドをエクスポートします。パフォーマンスの差はありません。この 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 リリースページから protobuf コンパイラ (protoc) をバージョン 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
ファイルをハイブリッド API に切り替えます。
open2opaque setapi -api HYBRID $(find . -name "*.proto")
既存のコードは引き続きビルドされます。ハイブリッド 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)
もう一つの一般的な例は、構造体リテラルで protobuf メッセージを初期化することです。
return &logpb.LogEntry{
BackendServer: proto.String(host),
}
Opaque API では、同等の機能として Builder を使用します。
return logpb.LogEntry_builder{
BackendServer: proto.String(host),
}.Build()
このツールは、利用可能な書き換えを異なるレベルに分類します。-levels=red
引数は、人間のレビューを必要とするものを含め、すべての書き換えを有効にします。利用可能なレベルは次のとおりです。
- 緑: 安全な書き換え(高信頼度)。ツールが行うほとんどの変更が含まれます。これらの変更は綿密な確認を必要とせず、人間の監視なしに自動化によってコミットすることも可能です。
- 黄: (妥当な信頼度)これらの書き換えは人間のレビューが必要です。これらは正しいはずですが、確認をお願いします。
- 赤: 潜在的に危険な書き換えで、稀で複雑なパターンを変更します。これらは慎重な人間のレビューが必要です。例えば、既存の関数が
*string
パラメーターを取る場合、関数がポインターに書き込むことでフィールド値を変更しようとしていた場合(*foo = "value"
)、一般的な修正であるproto.String(msg.GetFoo())
の使用は機能しません。
多くのプログラムは緑色の変更のみで完全に移行できます。proto メッセージまたはファイルを Opaque API に移行する前に、すべてのレベルのすべての書き換えを完了する必要があります。その時点では、コード内に直接的な構造体アクセスは残りません。
ステップ3. 移行と検証
移行を完了するには、open2opaque
ツールを使用して、.proto
ファイルを Opaque API に切り替えます。
open2opaque setapi -api OPAQUE $(find . -name "*.proto")
ここで、まだ Opaque API に書き換えられていない残りのコードはコンパイルされなくなります。
必要に応じて、単体テスト、統合テスト、およびその他の検証手順を実行してください。
質問はありますか?問題がありますか?
まず、Opaque API FAQ を確認してください。それで質問が解決しない場合や問題が解決しない場合は、「どこで質問したり問題を報告できますか?」を参照してください。