Go Opaque API移行
Opaque APIは、Goプログラミング言語向けProtocol Buffers実装の最新バージョンです。古いバージョンは現在、Open Struct APIと呼ばれています。導入については、Go Protobuf: Releasing the Opaque APIブログ投稿をご覧ください。
Opaque APIへの移行は、プロトメッセージごと、または.proto
ファイルごとに、api_level
機能を可能な値の1つに設定することで段階的に行われます。
API_OPEN
はOpen Struct APIを選択します。これはエディション2023にバックポートされたため、Goプラグインの古いバージョンでは認識されない場合があります。API_HYBRID
はOpenとOpaqueの間のステップです。ハイブリッドAPIにはアクセサーメソッドも含まれています(そのため、コードを更新できます)が、以前と同様に構造体フィールドをエクスポートします。パフォーマンスの違いはありません。このAPIレベルは移行に役立つだけです。API_OPAQUE
はOpaque APIを選択します。これはエディション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
注意
自動移行アプローチで問題が発生した場合は、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
ファイルを更新して、protobufモジュールをバージョン1.36.0以降で使用します。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)
もう1つの一般的な例は、構造体リテラルでprotobufメッセージを初期化することです。
return &logpb.LogEntry{
BackendServer: proto.String(host),
}
Opaque APIでは、同等のものはビルダーを使用することです。
return logpb.LogEntry_builder{
BackendServer: proto.String(host),
}.Build()
ツールは利用可能な書き換えを異なるレベルに分類します。-levels=red
引数は、人間のレビューが必要なものを含むすべての書き換えを有効にします。以下のレベルが利用可能です。
- 緑: 安全な書き換え(高い信頼性)。ツールが行う変更のほとんどが含まれます。これらの変更は綿密な検討を必要とせず、人間の監視なしに自動化によって提出することも可能です。
- 黄: (妥当な信頼性)これらの書き換えには人間のレビューが必要です。これらは正しいはずですが、レビューしてください。
- 赤: 潜在的に危険な書き換えで、稀で複雑なパターンを変更します。これらには慎重な人間のレビューが必要です。たとえば、既存の関数が
*string
パラメータを受け取る場合、proto.String(msg.GetFoo())
を使用する一般的な修正は、関数がポインタに書き込むことによってフィールド値を変更することを意図していた場合(*foo = "value"
)には機能しません。
多くのプログラムは、緑の変更のみで完全に移行できます。プロトメッセージまたはファイルをOpaque APIに移行する前に、すべてのレベルのすべての書き換えを完了する必要があります。その時点で、コードには直接的な構造体アクセスは残りません。
ステップ3. 移行と検証
移行を完了するには、open2opaque
ツールを使用して、.proto
ファイルをOpaque APIに切り替えます。
open2opaque setapi -api OPAQUE $(find . -name "*.proto")
これで、Opaque APIにまだ書き換えられていない残りのコードはコンパイルされなくなります。
ユニットテスト、統合テスト、その他の検証手順があれば実行してください。
質問、問題点?
まず、Opaque API FAQをご覧ください。それでも質問に答えられない、または問題を解決できない場合は、質問したり問題を報告したりするにはどこですか?を参照してください。