FastAPI 演進史(上):型別提示、PEP 649 與 Pydantic v2
我好幾年來一直避免創造一個新框架。一開始,我試著用許多不同的框架、外掛和工具,解決 FastAPI 涵蓋的所有功能……到了某個時間點,除了自己創造一個東西之外,別無選擇。
FastAPI 作者 Sebastián Ramírez(tiangolo)在官方文件〈歷史、設計與未來〉中寫下的這段自白,道出了這個現代 Python Web 框架的起點。
FastAPI 於 2018 年 12 月正式發布,比起 2010 年問世的 Flask 晚了整整八年。但在 2024 年 JetBrains 的 Python 開發者調查中,FastAPI 以 38% 的使用率超越了 Django(35%)與 Flask(34%),躍升為 Python 生態系中採用度最高的 Web 框架。
FastAPI 能在成熟的 Python Web 市場中迅速普及,關鍵在於精準踩中了三個技術轉捩點:Python 3.6+ 的變數註解語法、Starlette 奠定的非同步 ASGI 基礎,以及 Pydantic 將型別宣告轉化為執行時驗證的能力。
本文為上下兩篇系列文章的上篇,回顧 FastAPI 在 2018 至 2026 年間的技術演進史,探討它如何從一個組合式微框架,發展到與 Pydantic 一同影響 Python 型別註解標準的走向。
站在巨人的肩膀上:APIStar 的空位與 2018 年誕生
FastAPI 在官方文件的致謝與靈感清單中,完整列出了它所借鑑的前輩專案:從 Django REST Framework(DRF)學到自動化 API 文件的價值、從 Flask 繼承簡潔的微框架路由設計、從 Requests 汲取直覺的 HTTP 語意,並從 TypeScript 框架 NestJS 中借鑑依賴注入與編輯器優先的理念。
但在所有靈感來源中,影響最深遠的是 APIStar。FastAPI 官方稱自己為 APIStar 的「精神繼承者」,並留下了一句簡短的評價:
「它的存在,啟發了 FastAPI 的誕生。」(Inspired FastAPI to exist.)
Tom Christie's Transition (2018)
+-----------------------+ +-----------------------+
| APIStar | Pivoted | Starlette |
| (Typed API Framework) | ------> | (Async Toolkit) |
+-----------------------+ +-----------------------+
| |
| Left the niche open | ASGI base
v v
+---------------------------------------------------------+
| FastAPI (2018) |
| - Type hints + Pydantic |
| - Starlette on steroids |
+---------------------------------------------------------+
APIStar 是 DRF 作者 Tom Christie 於 2017 年打造的實驗性框架,率先探索「以型別提示宣告 Web API」的可能。然而到了 2018 年 9 月,Tom Christie 宣布將 APIStar 轉型為與框架無關的 API 工具組,並將開發重心轉向新問世的 ASGI 微框架 Starlette。
APIStar 轉型後,以型別提示打造 API 框架的方向留下了空位;同時,Starlette 提供了新的非同步基礎。FastAPI 正是在這兩個條件下誕生。
三個月後的 2018 年 12 月 5 日,Sebastián Ramírez 在 GitHub 提交了第一個 commit,並於 12 月 8 日向 PyPI 發布 FastAPI 0.1.0。
核心設計哲學:型別提示從「註解」化為「規格」
在架構分層上,FastAPI 由底至頂分為三層:
- Uvicorn:最底層的高效能 ASGI 伺服器,負責連線管理與網路傳輸。
- Starlette:中間層的非同步微框架,提供路由分發、中介軟體(Middleware)與 WebSocket 支援。
- FastAPI:最上層的封裝,在 Starlette 基礎上整合資料驗證、依賴注入與 OpenAPI 文件生成。
FastAPI 官方將自己形容為「加了類固醇的 Starlette」(Starlette on steroids)。這意味著 FastAPI 的效能天花板直接取決於 Starlette 與 Uvicorn,而底層的非同步行為與中介軟體機制也與 Starlette 深度綁定。
+-------------------------+
| FastAPI |
| - Validation (Pydantic) |
| - Dependency injection |
| - OpenAPI docs (/docs) |
+-------------------------+
| Starlette |
| - Routing |
| - Middleware |
| - WebSockets |
| - Background tasks |
+-------------------------+
| Uvicorn |
| - ASGI web server |
| - uvloop + httptools |
+-------------------------+
FastAPI 的核心做法,是讓 Python 型別提示(Type Hints)不再只是靜態分析的參考,也成為框架驗證請求資料、產生 API 文件的依據。
當開發者在路由中宣告 item_id: int,同一份型別資訊就能用在四個環節:
- 路徑取值:自動從 URL 解析對應參數。
- 資料轉換與驗證:自動將請求字串轉型為整數;若型別不符,立即回傳結構化的 HTTP 422 錯誤。
- 生成 OpenAPI 規格:即時將參數型別輸出至 OpenAPI JSON Schema,驅動
/docs的 Swagger UI 介面。 - 編輯器型別推導:讓 VS Code 與 PyCharm 能即時提供自動完成與靜態型別檢查。
Sebastián Ramírez 在設計之初,便反覆驗證型別提示在涵蓋約 80% 開發者的主流編輯器中的實際效果。FastAPI 不僅追求伺服器端的高效,更將開發者在編輯器中的流暢度與自動補全體驗視為第一優先順序。
八年演進時間軸:從微框架到現代工具鏈
FastAPI 的版本號碼長期維持在 0.x,但每個次版號的躍升往往伴隨重大的架構迭代。回顧 2018 至 2026 年的發布軌跡,整體演進可劃分為三個關鍵階段:
| 版本 | 發布日期 | 核心變更與里程碑 |
|---|---|---|
0.1.0 | 2018-12-08 | 第一個公開發布版本 |
0.93.0 | 2023-03-07 | 引入 lifespan 非同步上下文管理機制 |
0.95.0 | 2023-03-18 | 支援並全面推薦標準 Annotated 語法宣告依賴 |
0.100.0 | 2023-07-07 | 正式支援 Pydantic v2,啟動長期雙軌相容 |
0.111.0 | 2024-05-03 | 推出官方 CLI 工具:fastapi dev 與 fastapi run |
0.112.0 | 2024-08-02 | 核心套件輕量化,標準功能改為 fastapi[standard] |
0.126.0 | 2025-12-20 | 正式停止支援 Pydantic v1,最低要求 Pydantic 2.7.0 |
0.130.0 | 2026-02-22 | 導入 Pydantic Rust 引擎序列化 JSON,大幅降低 CPU 開銷 |
0.135.0 | 2026-03-01 | 原生支援 Server-Sent Events(SSE) |
階段一:2023 年語法與相容性分水嶺
2023 年是 FastAPI 寫法現代化的關鍵轉折。在短短五個月內,官方相繼推出了 lifespan、Annotated 依賴注入語法,以及對 Pydantic v2 的支援。
早期寫法 user: User = Depends(get_user) 把 Depends 放在參數的預設值位置。直接呼叫函式進行單元測試時,這個參數會拿到 Depends 物件而非真正的使用者資料,產生非預期行為;靜態檢查工具也容易誤判。
0.95.0 改為推薦 Python 標準函式庫的 Annotated[User, Depends(get_user)],把參數型別與 Depends 放在同一個註解中,也更方便跨路由重用型別定義。
同時,0.93.0 棄用了過往分散的 @app.on_event("startup") 與 @app.on_event("shutdown") 事件處理器,改採基於 ASGI 標準的 lifespan 上下文管理器,讓資料庫連線池與全域狀態的生命週期管理更加清晰可控。
階段二:2024 年開發者工具鏈成形
隨著生態系成熟,FastAPI 的著眼點從「框架核心」擴充至「全流程開發體驗」。
官方推出的 CLI(fastapi dev、fastapi run)簡化了傳統 Uvicorn 繁雜的啟動參數,並將常用的選用套件打包為 fastapi[standard],讓開發者在極簡安裝與開箱即用之間取得更靈活的選擇空間。
階段三:2025 至 2026 年清理歷史包袱與效能突破
在維持了兩年半的相容過渡期後,FastAPI 於 2025 年底停止支援 Python 3.8/3.9 與 Pydantic v1。
包袱卸除後,FastAPI 在 0.130.0 中全面整合 Pydantic 底層 Rust 引擎(pydantic-core)的能力:宣告回應模型或 Pydantic 回傳型別的回應,不再經過 Python 層級逐欄位轉換的 jsonable_encoder,而是直接以 Rust 進行 JSON 序列化,使高吞吐 API 的序列化延遲與 CPU 開銷顯著降低。相關歷史細節均完整記錄於 FastAPI 版本發布日誌。
直面語言標準:PEP 563 危機與 PEP 649 的轉折
FastAPI 發展史上影響最深遠的一件事,是它與 Pydantic 聯手改變了 Python 語言特性的走向。
危機爆發:字串化註解的威脅
2017 年提出的 PEP 563(延後求值的型別註解)旨在解決型別循環參考與模組載入效能問題。其做法是在編譯期將所有型別註解轉換為純字串(即 from __future__ import annotations 的行為)。
對純靜態檢查工具(如 mypy)而言,字串化註解影響甚微;但對於在執行時需要解析真實型別物件的 Pydantic 與 FastAPI 而言,字串化意味著執行時必須仰賴昂貴且不穩定的動態 eval()。一旦遇到局部作用域、閉包變數或巢狀型別定義,eval() 便會頻繁失敗。
原定在 Python 3.10 讓所有型別註解都變成字串的這項計畫,一旦實施,將直接癱瘓需要在執行時讀取真實型別的現代 Web 生態。
Python 3.10 Plan (PEP 563)
+-------------------------------+
| Stringified annotations |
| def f(x: int) -> str: |
| annotations = {'x': 'int'} |
+-------------------------------+
|
| Breaks runtime reflection
v
❌ Broke Pydantic & FastAPI
Community Resolution (PEP 649 / 749)
+-------------------------------+
| Deferred evaluation |
| - Via descriptors (functions) |
| - Computed only when read |
+-------------------------------+
|
| Preserves real type objects
v
✅ Adopted in Python 3.14 (2025)
社群協商與指導委員會決策
2021 年 4 月 15 日,Pydantic 作者 Samuel Colvin 在 GitHub 上發布緊急倡議:
「簡而言之,Pydantic 在延後求值的註解下運作不良,未來可能也永遠無法良好運作。」
該議題迅速引發開發者社群與 Hacker News 的廣泛討論。
五天後的 4 月 20 日,Python 指導委員會成員 Thomas Wouters 在 python-dev 郵件討論群中正式宣布撤回 PEP 563 在 Python 3.10 的預設化決策:
「我們在此時此刻的決定是:我們承擔不起 PEP 563 帶來的相容性破壞風險。」
隨後,社群轉向支持 Larry Hastings 提出的 PEP 649(後續由 PEP 749 完善實作細節)。該機制將型別求值包裝為惰性函式,唯有在程式碼明確讀取註解時才進行計算,既避免了循環參考,也保住了在執行時取得真實型別物件的能力。
這場長達數年的討論最終在 Python 3.14(2025 年 10 月發布)定案,PEP 649 正式納入語言標準,而 PEP 563 則被官方標註為「從未成為預設行為,並已由 PEP 649/749 取代」。
這場轉折代表 Python 官方正式承認:執行時型別反射(Runtime Type Reflection)已不再是邊陲特例,而是現代 Python 應用開發的核心基石。
NOTE
Pydantic v2 遷移:組合式架構的紅利與代價
FastAPI 選擇將資料驗證完全委託給 Pydantic,為框架帶來了極簡的程式碼結構,但同時也意味著 FastAPI 的演進與外部專案深度綁定。
Rust 重寫與相容性挑戰
2023 年 6 月,Pydantic v2 正式發布。為了追求極致效能,Pydantic 將核心驗證邏輯以 Rust 重寫為獨立的 pydantic-core,帶來了顯著的運算效能提升,但伴隨而來的是底層 API 的破壞性變更。
FastAPI 在一週內推出了 0.100.0 支援 Pydantic v2。但為了保護下游龐大的企業應用,Sebastián Ramírez 選擇了長達兩年半的雙軌相容過渡期。
這段過渡分三步進行:2023 年 7 月的 0.100.0 同時支援 v1 與 v2;2025 年 10 月的 0.119.0 允許同一專案混用新舊模型;到 2025 年底的 0.126.0–0.128.0,才正式淘汰 v1 與相容層。FastAPI 因此給了社群與第三方套件時間完成遷移。
這段歷程展現了組合式架構的核心權衡:不自行造輪子,並不代表免除維護成本。框架必須替下游使用者承擔核心相依套件大版本升級的相容代價。
⭐️容器部署哲學:「單容器單行程」的雲原生轉向
對於維運與 DevOps 工程師而言,FastAPI 官方部署建議的變遷,清晰反映了容器化架構在過去數年間的思維演進。
Phase 1: Multi-Process in Container
+------------------------------+
| Single Pod |
| +--------------------------+ |
| | Gunicorn (master) | |
| +--------------------------+ |
| | | |
| v v |
| +----------+ +----------+ |
| | Worker | | Worker | |
| +----------+ +----------+ |
+------------------------------+
|
v
Phase 2: Cloud Native (K8s)
+------------------------------+
| Kubernetes |
| +--------------------------+ |
| | HPA scaling | |
| +--------------------------+ |
| | | | |
| v v v |
| +------+ +------+ +------+ |
| | Pod | | Pod | | Pod | |
| | (1P) | | (1P) | | (1P) | |
| +------+ +------+ +------+ |
+------------------------------+
第一階段:以 Gunicorn 管理 Uvicorn Worker
在 FastAPI 初期,Uvicorn 尚不具備完善的行程崩潰重啟機制。當時官方推薦使用 tiangolo/uvicorn-gunicorn-fastapi 映像檔,透過 Gunicorn 主行程來監控並管理多個 Uvicorn worker 行程。
第二階段:棄用多行程映像,叢集部署改採單容器單行程
隨著 Uvicorn 自身穩定度提升以及 Kubernetes 成為部署主流,官方正式將該 Gunicorn 映像宣告棄用,並在官方部署指引中重塑了容器化部署原則:
「如果你使用 Kubernetes 等容器叢集管理系統,請在叢集層級處理副本擴充,每個容器內只需運行單一 Uvicorn 行程。」
這項原則以叢集為前提。若只在單台伺服器上以 Docker Compose 部署,缺少叢集層級的副本與負載平衡,官方文件仍示範在單一容器內以 --workers 啟動多個 worker 行程。
容器內再放一層行程管理器,會增加健康狀態判斷與資源配置的複雜度。改由叢集管理副本、每個容器只執行一個行程後,這三項維運工作更容易對應到 Pod:
| 維運面向 | 早期多行程容器(Gunicorn + Uvicorn) | 現代雲原生架構(單容器單行程) |
|---|---|---|
| 健康檢查 | 易出現「Master 存活但 Worker 崩潰」的灰色狀態 | 探針結果直接對應唯一的行程,容器異常時由 kubelet 重啟 |
| 資源隔離 | 多 Worker 共享容器,記憶體預估困難易引發 OOM | Request/Limit 精準對應單一行程 |
| 擴充控制 | 需手動計算並調整容器內的 Worker 數量 | 叢集層級由 HPA 依負載自動水平擴充 |
第三階段:現代 CLI 整合
隨著 fastapi dev 與 fastapi run 的推出,現代 Dockerfile 已簡化為標準宣告:
CMD ["fastapi", "run", "app/main.py", "--port", "80"]
官方在 0.116.0 亦加入 fastapi deploy,將部署路徑進一步延伸至雲端託管服務。
文件即產品:從互動式規格到 Agent Skills
開發者能快速理解並開始使用 FastAPI,文件設計是關鍵原因之一。其文件並非單純的 API 參考手冊,而是漸進式的實戰導引,涵蓋了 Python 型別系統與非同步機制的基礎概念。
隨 API 宣告產生的互動式文件
透過整合 OpenAPI 與 Swagger UI / ReDoc,FastAPI 讓後端工程師無需額外維護 API 文件,啟動服務即可在 /docs 進行互動式除錯。這大幅降低了前後端協作的溝通成本,並使 API 規格能直接作為客戶端程式碼生成工具的輸入來源。
面向 AI 時代的文件演進
隨著專案擴充與 AI 輔助開發的普及,FastAPI 的文件體系經歷了兩次重要迭代:
- LLM 自動化翻譯管線:在 2025 年底捨棄依賴志工審查的傳統流程,改由 LLM 自動化管線維護多語系翻譯,讓全球 13 種語言版本的文件即時同步。
- Library Agent Skills:2026 年初在
0.133.1中引入「FastAPI Agent Skill」,將框架使用慣例與型別規格打包為專門供 AI 程式設計助理(如 Claude、Copilot)讀取的標準技能檔。
當程式碼生成日益由 AI 輔助,讓 AI 模型能準確理解並產出符合框架最佳實踐的程式碼,已成為新一代開源專案維持生態競爭力的新面向。
結語:八年演進的三條核心脈絡
回顧 FastAPI 自 2018 年誕生至 2026 年的演進歷程,其發展清晰展現了三條主線:
- 全面擁抱並推動 Python 標準:從框架專屬的寫法回歸標準的
Annotated與lifespan,甚至反向推動 PEP 649 定案,FastAPI 已成為形塑現代 Python 語言特性的重要力量。 - 組合式架構的平衡術:站在 Starlette 與 Pydantic 的基礎上實現快速創新,同時以耐心承擔生態系大版本升級的相容成本。
- 從框架邁向全流程開發平台:從單純的路由與驗證框架,擴充為涵蓋 CLI、雲端部署乃至 AI Agent Skills 的全方位現代化工具鏈。
當一個微框架的邊界不斷擴充,並逐步跨足商業託管服務時,開源專案的社群治理機制、商業化路徑、效能競品的挑戰以及在 AI 時代的定位,將面臨哪些全新的矛盾與抉擇?
這些關鍵議題,將在下篇中深入探討。