[ADP-5] DRAFT ADP 導入指南 第一階段
介紹
對於新接觸 ADP 的人來說,這可能會讓人感到不知所措。本指導強調了 ADP 中一些最重要的原則,確保開發者了解從何開始。
INFO
本文內容偏向於設計內部 API (以 COMPONENT_INTENRAL
) 作為 API 受眾,並想要以 ADP 作為設計規範的起步點的開發團隊/開發者,因此會盡可能地只揭示重點規範。其他非必要規範在第二階段導入文件中會另外標出。 關於外部用公用 API,理論上你必須要盡可能的滿足大部分的規範,除非該 API 受眾為特定合作廠商並且有特殊要求。
在開始之前
深呼吸。ADP 旨在提供 API 設計原則的全面覆蓋,而不是讓你感到不知所措。可能看起來很龐大,但其目的是確保全面性,並非為了讓開發人員感到沮喪。如果你對任何設計方面有疑慮,隨時可以與我討論(儘管變更可能不會得到保證,因為這取決於各種因素)。
- 如果你的 API 是
COMPONENT_INTERNAL
以下用途,基本上你可以(MAY)修改任何原則以解決你實行上遇到的困境。- 建議(RECOMMENDED)對項目中所做的變更提供回饋,以告知 ADP 維護者是否需要更新原則。
- 修改過的原則應(SHOULD)在整個應用(指 application 或 project)中保持一致。
選擇 API 先行或代碼先行
雖然我們建議 API 先行,但我們也理解到有時候需要先進行代碼實現,然後根據需求進行文件編寫。API 先行的方法強調在實現任何代碼之前先設計 API,這樣可以確保 API 自始至終都能滿足消費者(不管這個消費者是內部開發者還是外部開發者)的需求,並且允許前端和後端分開進行工作。此外,這種方法還可以方便進行 API 測試,在 API 實際開發完成之前,只要先設計好 API 文件就能預先創建測試環境。
什麼是 API 先行?
API 先行是一種開發方法,在編寫任何代碼之前設計 API 並達成共識。這確保所有利益相關者對 API 的功能和需求有清晰的理解,從而更好地對齊開發和業務目標。
參見 API 先行。
選擇合適的 API 文件工具
API 文件在我們的用例中現在是 OpenAPI 格式,由簡單的 JSON/YAML 文件組成。我們建議使用 YAML 文件格式,因為它易於拆分;不過,也有工具可以在 YAML 和 JSON 之間轉換,所以不必過於擔心文件格式。
雖然編輯 YAML/JSON 不會太困難,但理解如何編輯 OpenAPI 內容仍然需要學習曲線;我們建議選擇合適的 OpenAPI 編輯器。Apidog 是一個不錯的選擇,但其他工具如 Swagger Editor 或 Stoplight 也可以考慮。
記住,最終輸出的 YAML/JSON 文件是最重要的,線上編輯器僅僅是一個方便使用的工具。
apidog
需要注意的是,使用 apidog 作為編輯器時有某些限制。
例如,它不允許將回應 MIME 類型自定義為自定義 JSON 格式,並且在端點中添加自定義屬性(如 x-audience)可能會不直覺。
儘管有這些限制,apidog 仍然是啟動 API 文件的合適起點。
我們鼓勵你在自己喜歡的編輯器中編輯原始 API 文件,在你熟悉 OpenAPI 之後。
OpenAPI 相關
關於 OpenAPI 文件的撰寫,可參考OpenAPI 完整示例,以及從 OpenAPI概述開始的規範。其中比較重要的參數如下:
定義 API 受眾
API 受眾將影響 API 規範的嚴格程度。內部 API 預期會更靈活,而外部 API 則會更嚴格。了解你的受眾有助於做出有效滿足其需求的設計決策。對於內部 API 而言,我們可以直接在 OpenAPI 文件的 info 欄位標記 X-Audience 為 COMPONENT_INTERNAL
或者不標示,只要確保這份文件僅在內部團隊中流動。
然而,等到我們有足夠的 API 累積,要建立公司級別的 API Portal(內部)時,我們希望到時候能夠重新審視並將每個 API 文件加上受眾欄位。
請參見 API 受眾。
定義 OperationId
OperationId 是一個簡潔且明確的識別字,用來描述 API 的目的或操作。它將在任何 OpenAPI 查看器中顯示為該操作的名稱。請參考 OperationID。
版本控制
選擇你的版本控制策略:對於內部特定的 API,我們理解它們可能會非常快速地迭代。因此,我們定義內部用途的 API 可以不進行版本控制。然而,對於外部 API,應遵循語義版本控制(SemVer),以清晰地向消費者傳達變更。
參見 API 版本控制 獲取更多信息。
將 API 要求分解為 API 組件
如果你選擇 API 先行,請坐下來試著寫下「API 用戶故事」。這將幫助你從消費者的角度定義 API 的功能和需求。
例如,假設你正在為一個簡單的電子商務平台設計 API。你的 API 用戶故事可能看起來像這樣:
「作為一名客戶,我希望能夠查看我的訂單歷史,以便跟踪我的過去購買。」
這個 API 用戶故事可以指引你的 API 設計,以確保它滿足客戶的需求。實際上,一個(RESTful)API 可以由幾個組件組成:
- 路徑
- HTTP 動詞
- (可選)查詢參數
- (可選)標頭,包括請求和回應
- (可選)請求有效負載
- 回應代碼
- (可選)回應主體
設計 RESTful API 的過程沒有秘密;就是將正確的元素放在正確的位置。這對於新手 API 設計師來說可能是一個挑戰,無論你是前端還是後端開發人員。
這個"把需求分解為 API 部件"的過程會需要一些經驗跟學習,可以多看看已知的公共 API 獲得靈感。
URL/路徑設計
路徑設計是 API 設計第一個重要部件,也是其中特別具挑戰性的方面。
在 API 審查期間(如果需要的話),重做 URL 設計是一件常見的事,新手可能不太容易一次到位。
路徑必須表示出這個 API 的"明確意圖"所指向的資源,並與 HTTP 動詞結合使用,讓開發者能簡單地看出這個 API 用途。
以上面的 API 故事為例,我們應該使用類似這樣的設計:
GET /order-history
而非
GET /api/get
如何圍繞「資源」進行設計,請參考 資源導向設計。
HTTP方法
HTTP 動詞是 RESTful 中第二重要的部件,他與路徑一同用來表達這個 API "主要" 想要做到的事情為何。
基本上我們最常使用的會是 GET,POST。DELETE/PATCH/PUT 使用情境較少。
請參閱 HTTP方法相關的數個規範。
關於冪等性與冪等鍵:建議在需要時候導入即可。
負載/回應設計
請參見 ADP-701: JSON 結構和嵌套 獲取有效結構化負載和回應的原則。確保你的 API 回應一致並提供有意義的錯誤消息。
在設計負載/回應的欄位時,應遵循 OpenAPI 中的格式約定而非只指定欄位為字串,請參見 OpenAPI 格式約定。
INFO
關於欄位命名大小寫約定:camelCase/snake_case 沒有對錯,本規範建議使用 camelCase,但是在小組內部同意的情況下可自行使用一致的 snake_case。
預期以後 API 治理成熟度提升的情況下,我們會考慮回頭來審視是否需要完全統一的必要性。
錯誤設計
API 錯誤是必要但很常被忽視的一塊,但設計錯誤回應對於良好且一致的開發者體驗(DX)是必不可少的。請盡可能遵循 ADP-401: HTTP 問題基礎 中的原則,以標準化 API 之間的錯誤回應。
本規範認為錯誤設計優先程度高於其他原則。
一個基本問題回應如下:
{
"type": "about:blank",
"title": "human readable string to the main part of the problem",
"status": "HTTP Status",
"detail": "human readable string of how to fix the problem"
}
事件設計
在設計事件相關的 API 時,請考慮實作 事件作為 API 設計的一部分 和 CloudEvents 中概述的原則。確保事件符合規範,事件消費者(event consumers)便能夠輕鬆理解和處理它們。
關於標頭
HTTP 定義了一系列標準標頭,也允許客製化標頭。有時候你想要達成的某件事情可能已經被標準標頭解決了,就不需要透過回應/負載/查詢參數來做。有時候你可能需要設計新的客製化標頭。參閱 常用HTTP標頭。
關於查詢參數
查詢參數並沒有嚴格的規範而只有一些常用查詢約定,請參考 查詢參數約定。
回應狀態碼
參閱 HTTP狀態碼,針對一個 API 端點請至少定義一組 200(2xx) 回應,以及4xx/5xx回應。
總結
探索不斷擴展的 OpenAPI 完整示例 以獲取額外的 API 設計靈感。我努力創建盡可能遵循 ADP 指導方針的 API 示例。
請隨時與我討論你的 API 設計。
Changelog
2024.09.26
修改第一階段導入必要。