Go Opaque API 遷移
Opaque API 是 Protocol Buffers 針對 Go 程式語言實作的最新版本。舊版本現在稱為 Open Struct API。請參閱Go Protobuf:發布 Opaque API 部落格文章以取得簡介。
遷移至 Opaque API 是逐步進行的,以每個 proto 訊息或每個 .proto
檔案為基礎,透過將 Protobuf Editions 功能 api_level
選項設定為其中一個可能的值
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
對應旗標 (類似於import 路徑的 M
旗標)
protoc […] --go_opt=apilevelMhello.proto=API_OPAQUE
命令列旗標也適用於仍使用 proto2 或 proto3 語法的 .proto
檔案,但如果您想要從 .proto
檔案中選取 API 層級,則需要先將所述檔案遷移至 editions。
自動化遷移
我們盡力讓您盡可能輕鬆地將現有專案遷移至 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
檔案切換至 Hybrid API
open2opaque setapi -api HYBRID $(find . -name "*.proto")
您現有的程式碼將繼續建置。Hybrid API 是 Open 和 Opaque API 之間的中間步驟,它新增了新的存取器方法,但保持 struct 欄位可見。
步驟 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)
另一個常見的範例是使用 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())
的典型修復方法將無法運作。
許多程式可以使用綠色變更完全遷移。在您可以將 proto 訊息或檔案遷移至 Opaque API 之前,您需要完成所有層級的所有重寫,屆時您的程式碼中將不再有直接的 struct 存取。
步驟 3. 遷移與驗證
若要完成遷移,請使用 open2opaque
工具將您的 .proto
檔案切換至 Opaque API
open2opaque setapi -api OPAQUE $(find . -name "*.proto")
現在,任何尚未重寫為 Opaque API 的剩餘程式碼將不再編譯。
執行您的單元測試、整合測試和其他驗證步驟 (如果有的話)。
有問題嗎?遇到問題?
首先,查看Opaque API 常見問題。如果這無法回答您的問題或解決您的問題,請參閱我可以在哪裡提出問題或回報問題?