You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

9.1 KiB

產生 SDK

由於 FastAPI 建立在 OpenAPI 規格之上,其 API 能以許多工具都能理解的標準格式來描述。

這讓你能輕鬆產生最新的文件、多語言的用戶端程式庫(SDKs),以及與程式碼保持同步的測試自動化工作流程

在本指南中,你將學會如何為你的 FastAPI 後端產生 TypeScript SDK

開源 SDK 產生器

其中一個相當萬用的選擇是 OpenAPI Generator,它支援多種程式語言,並能從你的 OpenAPI 規格產生 SDK。

針對 TypeScript 用戶端Hey API 是專門打造的解決方案,為 TypeScript 生態系提供最佳化的體驗。

你可以在 OpenAPI.Tools 找到更多 SDK 產生器。

/// tip

FastAPI 會自動產生 OpenAPI 3.1 規格,因此你使用的任何工具都必須支援這個版本。

///

來自 FastAPI 贊助商的 SDK 產生器

本節重點介紹由贊助 FastAPI 的公司提供的創投支持公司維運的解決方案。這些產品在高品質的自動產生 SDK 之外,還提供額外功能整合

透過 贊助 FastAPI ,這些公司幫助確保框架與其生態系維持健康且永續

他們的贊助也展現對 FastAPI 社群(你)的高度承諾,不僅關心提供優良服務,也支持 FastAPI 作為一個穩健且蓬勃的框架🙇

例如,你可以嘗試:

其中有些方案也可能是開源或提供免費方案,讓你不需財務承諾就能試用。其他商業的 SDK 產生器也不少,你可以在網路上找到。🤓

建立 TypeScript SDK

先從一個簡單的 FastAPI 應用開始:

{* ../../docs_src/generate_clients/tutorial001_py310.py hl[7:9,12:13,16:17,21] *}

注意這些 路徑操作 為請求與回應的有效載荷定義了所用的模型,使用了 ItemResponseMessage 這兩個模型。

API 文件

如果你前往 /docs,你會看到其中包含了請求要送出的資料與回應接收的資料之結構(schemas)

你之所以能看到這些結構,是因為它們在應用內以模型宣告了。

這些資訊都在應用的 OpenAPI 結構中,並顯示在 API 文件裡。

同樣包含在 OpenAPI 中的模型資訊,也可以用來產生用戶端程式碼

Hey API

當我們有含模型的 FastAPI 應用後,就能用 Hey API 來產生 TypeScript 用戶端。最快的方法是透過 npx:

npx @hey-api/openapi-ts -i http://localhost:8000/openapi.json -o src/client

這會在 ./src/client 產生一個 TypeScript SDK。

你可以在他們的網站了解如何安裝 @hey-api/openapi-ts,以及閱讀產生的輸出內容

使用 SDK

現在你可以匯入並使用用戶端程式碼。大致看起來會像這樣,你會發現方法有自動完成:

你也會對要送出的有效載荷獲得自動完成:

/// tip

注意 nameprice 的自動完成,這是由 FastAPI 應用中的 Item 模型所定義。

///

你在送出的資料上也會看到行內錯誤:

回應物件同樣有自動完成:

含標籤的 FastAPI 應用

在許多情況下,你的 FastAPI 應用會更大,你可能會用標籤將不同群組的 路徑操作 分開。

例如,你可以有一個 items 區塊與另一個 users 區塊,並透過標籤區分:

{* ../../docs_src/generate_clients/tutorial002_py310.py hl[21,26,34] *}

使用標籤產生 TypeScript 用戶端

若你為使用標籤的 FastAPI 應用產生用戶端,產生器通常也會依標籤將用戶端程式碼分開。

如此一來,用戶端程式碼就能有條理地正確分組與排列:

在此例中,你會有:

  • ItemsService
  • UsersService

用戶端方法名稱

目前像 createItemItemsPost 這樣的產生方法名稱看起來不太俐落:

ItemsService.createItemItemsPost({name: "Plumbus", price: 5})

...那是因為用戶端產生器對每個 路徑操作 都使用 OpenAPI 內部的操作 ID(operation ID)

OpenAPI 要求每個操作 ID 在所有 路徑操作 之間必須唯一,因此 FastAPI 會用函式名稱路徑HTTP 方法/操作來產生該操作 ID,如此便能確保操作 ID 的唯一性。

接下來我會示範如何把它變得更好看。🤓

自訂 Operation ID 與更好的方法名稱

你可以修改這些操作 ID 的產生方式,讓它們更簡潔,並在用戶端中得到更簡潔的方法名稱

在這種情況下,你需要用其他方式確保每個操作 ID 都是唯一的。

例如,你可以確保每個 路徑操作 都有標籤,接著根據標籤路徑操作名稱(函式名稱)來產生操作 ID。

自訂唯一 ID 產生函式

FastAPI 會為每個 路徑操作 使用一個唯一 ID,它會被用於操作 ID,以及任何請求或回應所需的自訂模型名稱。

你可以自訂該函式。它接收一個 APIRoute 並回傳字串。

例如,下面使用第一個標籤(你通常只會有一個標籤)以及 路徑操作 的名稱(函式名稱)。

接著你可以將這個自訂函式以 generate_unique_id_function 參數傳給 FastAPI

{* ../../docs_src/generate_clients/tutorial003_py310.py hl[6:7,10] *}

使用自訂 Operation ID 產生 TypeScript 用戶端

現在,如果你再次產生用戶端,會看到方法名稱已改善:

如你所見,方法名稱現在包含標籤與函式名稱,不再包含 URL 路徑與 HTTP 操作的資訊。

為用戶端產生器預處理 OpenAPI 規格

產生的程式碼仍有一些重複資訊

我們已經知道這個方法與 items 相關,因為該字已出現在 ItemsService(取自標籤)中,但方法名稱仍然加上了標籤名稱做前綴。😕

對於 OpenAPI 本身,我們可能仍想保留,因為那能確保操作 ID 是唯一的。

但就產生用戶端而言,我們可以在產生前修改 OpenAPI 的操作 ID,來讓方法名稱更簡潔、更乾淨

我們可以把 OpenAPI JSON 下載到 openapi.json 檔案,然後用像這樣的腳本移除該標籤前綴

{* ../../docs_src/generate_clients/tutorial004_py310.py *}

//// tab | Node.js

{!> ../../docs_src/generate_clients/tutorial004.js!}

////

如此一來,操作 ID 會從 items-get_items 之類的字串,變成單純的 get_items,讓用戶端產生器能產生更簡潔的方法名稱。

使用預處理後的 OpenAPI 產生 TypeScript 用戶端

由於最終結果現在是在 openapi.json 檔案中,你需要更新輸入位置:

npx @hey-api/openapi-ts -i ./openapi.json -o src/client

產生新的用戶端後,你現在會得到乾淨的方法名稱,同時保有所有的自動完成行內錯誤等功能:

好處

使用自動產生的用戶端時,你會得到以下項目的自動完成

  • 方法
  • 本文中的請求有效載荷、查詢參數等
  • 回應的有效載荷

你也會對所有內容獲得行內錯誤提示。

而且每當你更新後端程式碼並重新產生前端(用戶端),新的 路徑操作 會以方法形式可用、舊的會被移除,其他任何變更也都會反映到產生的程式碼中。🤓

這也代表只要有任何變更,便會自動反映到用戶端程式碼;而當你建置用戶端時,如果使用的資料有任何不匹配,就會直接報錯。

因此,你能在開發週期的很早期就偵測到許多錯誤,而不必等到錯誤在正式環境的最終使用者那裡才出現,然後才開始追查問題所在。