Go Opaque API 遷移
Opaque API 是 Go 程式語言的 Protocol Buffers 實現的最新版本。舊版本現在稱為 Open Struct API。請參閱 Go Protobuf:釋出 Opaque API 部落格文章以獲取介紹。
遷移到 Opaque API 是增量進行的,基於每個 proto 訊息或每個 .proto 檔案,透過將 api_level 功能設定為其可能值之一來實現
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 之前,需要更新生成的 proto 程式碼的所有現有用法。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 釋出頁面 將 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 檔案切換到 Hybrid API
open2opaque setapi -api HYBRID $(find . -name "*.proto")
然後,重新編譯您的 protocol buffers。
您現有的程式碼將繼續構建。Hybrid API 是 Open 和 Opaque API 之間的一個步驟,它添加了新的訪問器方法但保持結構欄位可見。
步驟 2. open2opaque rewrite
要重寫您的 Go 程式碼以使用 Opaque API,請執行 open2opaque rewrite 命令
open2opaque rewrite -levels=red github.com/robustirc/robustirc/...
您可以指定一個或多個包或模式。
例如,如果您有這樣的程式碼
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 引數啟用所有重寫,包括那些需要人工審查的。以下是可用的級別
- green: 安全重寫(高置信度)。包括工具進行的大部分更改。這些更改不需要仔細檢視,甚至可以透過自動化提交,無需任何人工監督。
- yellow: (合理置信度) 這些重寫需要人工審查。它們應該是正確的,但請仔細審查。
- red: 潛在危險的重寫,改變了罕見而複雜的模式。這些需要仔細的人工審查。例如,當現有函式採用
*string引數時,典型的修復方法是使用proto.String(msg.GetFoo()),如果該函式旨在透過寫入指標來更改欄位值(*foo = "value"),則該方法不起作用。
許多程式可以透過僅進行綠色更改進行完全遷移。在您可以將 proto 訊息或檔案遷移到 Opaque API 之前,您需要完成所有級別的所有重寫,此時您的程式碼中不再存在直接的結構體訪問。
步驟 3. 遷移和驗證
要完成遷移,請使用 open2opaque 工具將您的 .proto 檔案切換到 Opaque API
open2opaque setapi -api OPAQUE $(find . -name "*.proto")
現在,任何尚未重寫為 Opaque API 的剩餘程式碼將不再編譯。
執行您的單元測試、整合測試和其他驗證步驟(如果有)。
有問題?有疑問?
首先,請檢視 Opaque API 常見問題。如果這不能回答您的問題或解決您的問題,請參閱 我可以在哪裡提問或報告問題?