本節提供 Fuchsia 平台 API 變更的 Fuchsia 貢獻者指南。開始之前,請先熟悉下列概念:
平台 API 的生命週期
Fuchsia 平台 API 應遵循生命週期:「已新增」→「已淘汰」→「已移除」→「已刪除」,如下圖所示:
以下各節說明如何以 API 開發人員的身分管理這個生命週期。
新增 FIDL API
請一律使用 @available
屬性為新的 FIDL 程式庫和元素加上註解。不穩定的 API 應在 HEAD
API 級別新增。請注意,使用 SDK 的合作夥伴可以指定 HEAD
API 級別,但這樣做無法保證 API/ABI 相容性。
例如:
@available(added=HEAD)
library fuchsia.examples.docs;
當 API 準備就緒,可穩定運作時,您應將其更新為 NEXT
的 added
。例如:
@available(added=NEXT)
library fuchsia.examples.docs;
NEXT
與 HEAD
類似,但 NEXT
中可用的 API 元素會自動新增至下一個發布的 API 級別。因此,如果您在 F23 的 API 凍結前一個星期,將我們的程式庫新增至 NEXT
,一個星期後,您會看到:
@available(added=23)
library fuchsia.examples.docs;
之後,包含 23 加入的所有 API 元素都必須受到支援,直到包含這些 API 元素的所有 API 級別停用為止。
如果 FIDL 程式庫有多個 .fidl
檔案,則程式庫應包含個別的 overview.fidl
檔案,並在該檔案中寫入 @available
屬性,以及說明程式庫的文件註解。詳情請參閱 FIDL 樣式指南。
"partner"
SDK 類別中的每個 API 都會在 CI/CQ 中進行靜態相容性測試。如果 API 以回溯不相容的方式變更,這些測試就會失敗。新程式庫不會指定 SDK 類別,因此無法向合作夥伴公開,也無法納入相容性測試,且 API 可自由變更。當 API 穩定且程式庫已完成 API 校正後,請指定 "partner"
類別。
替換 FIDL API
有時您需要用新的定義取代 API。如要在 API 級別 N
執行這項操作,請使用 @available(replaced=N)
註解舊定義,並使用 @available(added=N)
註解新定義。舉例來說,您可以透過以下方式變更 API 級別 5 的常數值:
@available(replaced=5)
const MAX_LENGTH uint32 = 16;
@available(added=5)
const MAX_LENGTH uint32 = 32;
淘汰 FIDL API
請務必讓 Fuchsia 平台能為仰賴平台 API 的開發人員提供流暢的轉換作業。其中一部分是提供充分的警告,說明日後會移除 API。停用是向開發人員傳達這項資訊的一種方式。
請務必在高於移除 API 的層級淘汰 API。當開發人員指定已淘汰的 API 時,會在建構時看到該 API 已淘汰的警告,請他們改用替代方案。您應附上附註,協助最終開發人員找到替代方案。例如:
protocol Example {
// (Description of the method.)
//
// # Deprecation
//
// (Detailed explanation of why the method is deprecated, the timeline for
// removing it, and what should be used instead.)
@available(deprecated=5, removed=6, note="use Replacement")
Deprecated();
@available(added=5)
Replacement();
};
API 淘汰和移除之間,至少須有一個 API 級別。例如:
// These are OK.
@available(deprecated=5, removed=6)
@available(deprecated=5, removed=100)
@available(added=5, deprecated=5)
// These will not compile.
@available(deprecated=5, removed=5)
@available(deprecated=5, removed=3)
移除 FIDL API
請注意,您必須先淘汰 API,才能將其移除。
如要移除在穩定版中新增的 API,請使用 @available
屬性的 removed
引數。舉例來說,如要移除在第 12 級已淘汰的 18 級方法,請按照下列步驟操作:
protocol Example {
@available(added=10, deprecated=12, removed=18, note="Use Go() instead")
Run() -> ();
};
在這個範例中,如果目標開發人員指定 10 到 17 之間 (含兩者) 的任何層級,就會看到 Run
方法的用戶端繫結,但如果目標開發人員指定 18 以上層級,就不會看到。只要平台支援 10 到 17 之間的任何級別,在 Fuchsia 平台上工作的開發人員就會看到 Run
方法的繫結,因為平台建構會指定所有支援的 API 級別。
一旦平台停止支援 10 到 17 之間的所有層級,您可以視需要從 FIDL 檔案中刪除 Run
方法。如果您在這之前就將其刪除,靜態相容性測試將會失敗,且需要獲得 //sdk/history/OWNERS 特別核准才能提交變更。
如要移除在不穩定的層級 (例如 NEXT
或 HEAD
) 新增的 API,只需從 FIDL 檔案中刪除該 API。
設計可順利演進的 API
這份評分標準著重於提升與多種平台版本的相容性。這些屬性可讓相容性盡可能容易維護,也是 FIDL API 評分標準的子集。
遵循 FIDL 樣式指南
FIDL 樣式規範可讓 FIDL 易於閱讀,並納入最佳做法。這些是一般最佳做法,無論 sdk_category 為何,都應遵循。
使用 FIDL 版本註解
FIDL 版本管理註解可讓程式庫、通訊協定和其他元素與特定 API 級別建立關聯。所有相容性推論都是根據 API 版本。這是如何表示 API 演進過程中的某個點。
請只在
NEXT
或HEAD
API 級別修改 API。只有在變更已準備好在下一個 Fuchsia 里程碑中發布時,才應在
NEXT
實作變更。請勿變更編號 API 級別。請參閱 version_history.json。
指定向量和字串的邊界
詳情請參閱:FIDL API 評量標準 - 指定向量和字串的邊界
使用列舉和布林值
由於布林值是二進位值,因此在製作相容性友善的 API 時,建議使用可具有多種狀態的列舉。這樣一來,如果需要額外的狀態,則可擴充列舉,而布林值則必須替換為其他類型。詳情請參閱:FIDL API 評量標準 - 避免使用布林值,除非有更多狀態可用。
使用彈性的列舉和位元
彈性列舉具有預設的不明成員,因此可輕鬆進化列舉。
只有在您非常確定不會擴充 strict
enum
和 bits
類型時,才應使用這類型別。strict
enum
和 bits
類型無法擴充,且若要將這些類型遷移至 flexible
,則必須為具有指定類型的每個欄位進行遷移。
詳情請參閱:FIDL 語言 - 嚴格與彈性模式
偏好使用表格而非結構
結構體和資料表都代表具有多個已命名欄位的物件。差異在於結構體在傳輸格式中具有固定的版面配置,也就是說,如果要修改結構體,就必須破壞二進位相容性。相較之下,資料表在線格格式中具有彈性的版面配置,這表示欄位「可以」隨時間新增至資料表,而不會破壞二進位相容性。
詳情請參閱:FIDL API 評量標準 - 我該使用結構體還是資料表?
使用開放式通訊協定,搭配靈活的方法和事件
一般來說,所有通訊協定都應為 open
,而這些通訊協定中的所有方法和事件都應為 flexible
。
將通訊協定標示為開放後,當不同元件可能在不同版本中建構時,您就能更輕鬆地處理移除的方法或事件,因為每個元件對存在哪些方法和事件的觀點不同。由於一般來說,我們都希望通訊協定具有彈性,因此建議您選擇開放式通訊協定,除非有理由選擇較封閉的通訊協定。
撕裂式通訊協定是其中一個可能的例外狀況,代表交易,其中唯一的雙向方法是必須嚴格的提交作業,而交易的其他作業可能會演變。如果通訊協定很小、不太可能變更,且預期會由用戶端實作,您可以將其設為 closed
,並將所有方法設為 strict
。這樣一來,用戶端就不必煩惱如何處理「不明互動」。不過,這類通訊協定無法新增或移除方法或事件。如果您決定要新增方法或事件,就必須定義新的分離通訊協定來取代現有通訊協定。
更多資訊:
使用錯誤語法
錯誤語法用於指定方法會傳回值,或傳回代表錯誤的 int 或列舉。
請使用自訂錯誤列舉,而非 zx.Status
定義及控制網域時,請使用專門建構的列舉錯誤類型。舉例來說,在通訊協定專門建構時定義列舉,且傳達錯誤的語義是唯一的設計限制。
當您遵循明確定義的規格 (例如 HTTP 錯誤代碼) 時,請使用特定領域的列舉錯誤類型,而列舉是一種符合人體工學的方式,可用來表示規格規定的原始值。
詳情請參閱:FIDL API Rubric - 偏好用於錯誤的網域專用列舉。
請勿使用其他程式庫的宣告
如果公用 API 的類型和組合通訊協定在語意上相同,那麼重複使用這些類型和組合通訊協定會是個好方法,但也容易出錯。