FastAPI
API 文件(OpenAPI / Swagger / ReDoc)
主題:自動產生文件 /docs / /redoc
簡介
在現代的微服務與前後端分離架構中,API 文件化 已成為必備條件。良好的文件不只協助前端開發者快速了解介面規格,也能減少溝通成本、提升測試效率。
FastAPI 內建 OpenAPI(以前稱 Swagger)規範的自動產生功能,開發者只需要寫好路由與 Pydantic 模型,即可在瀏覽器看到即時更新的 Swagger UI(/docs)或 ReDoc(/redoc)文件。
本文將從概念說明、實作範例、常見陷阱與最佳實踐,帶你一步步掌握 FastAPI 的文件自動產生機制,讓你的 API 不再是「黑盒子」。
核心概念
1. OpenAPI 與 FastAPI 的整合
OpenAPI(原 Swagger)是一套描述 RESTful API 的規範,包含路徑、參數、回傳型別、認證方式等資訊。FastAPI 在啟動時會自動把所有路由、依賴、Pydantic 模型「翻譯」成符合 OpenAPI 3.0 的 JSON 檔案,並提供兩個 UI 供開發者即時瀏覽:
| UI | 路徑 | 特色 |
|---|---|---|
| Swagger UI | /docs |
互動式測試、支援多種 HTTP 方法、介面較為直觀 |
| ReDoc | /redoc |
版面較為正式、支援左側目錄、適合正式文件發佈 |
只要你的 FastAPI 應用 沒有關閉 這兩個路徑,文件就會自動產生,且會隨程式碼變更即時更新。
2. 為什麼同時提供 /docs 與 /redoc?
- Swagger UI 讓開發者可以直接在瀏覽器點擊「Try it out」執行請求,適合開發階段快速驗證。
- ReDoc 以更清晰的排版呈現 API 結構,常被用於對外說明文件或內部知識庫。
兩者皆遵循同一套 OpenAPI 規範,保持資訊一致性。
3. 自訂文件資訊
FastAPI 允許在建立 FastAPI() 物件時傳入 title、description、version、terms_of_service、contact、license_info 等參數,這些資訊會直接寫入 OpenAPI JSON,於 UI 上呈現。這對於 API 版本管理、版權聲明、聯絡方式 等實務需求尤為重要。
程式碼範例
以下範例均採用 Python 3.9+、FastAPI 0.110+ 為前提,請先安裝:
pip install fastapi uvicorn
範例 1:最小 FastAPI 應用與自動文件
# main.py
from fastapi import FastAPI
app = FastAPI() # 直接使用預設 title、version
@app.get("/ping")
def ping():
"""
簡單的健康檢查端點
"""
return {"message": "pong"}
執行
uvicorn main:app --reload後,瀏覽器開啟http://127.0.0.1:8000/docs即可看到自動產生的 Swagger UI,/redoc則呈現 ReDoc。
範例 2:使用 Path、Query 參數與型別提示
from fastapi import FastAPI, Query, Path
app = FastAPI(title="商品查詢 API", version="1.2.0")
@app.get("/items/{item_id}")
def read_item(
item_id: int = Path(..., description="商品的唯一 ID"),
q: str | None = Query(None, max_length=50, description="可選的搜尋關鍵字")
):
"""
取得單一商品資訊。若提供 `q`,會回傳搜尋提示。
"""
result = {"item_id": item_id, "query": q}
return result
- Path 參數使用
Path物件,可加入說明、驗證規則。 - Query 參數則透過
Query物件設定預設值、長度限制等,文件會自動顯示這些限制。
範例 3:回傳模型(Pydantic)與驗證
from fastapi import FastAPI
from pydantic import BaseModel, Field
from typing import List
app = FastAPI(title="圖書館 API")
class Book(BaseModel):
id: int = Field(..., example=1)
title: str = Field(..., example="Python 程式設計")
author: str = Field(..., example="王小明")
tags: List[str] = Field(default_factory=list, example=["程式", "Python"])
@app.post("/books/", response_model=Book, status_code=201)
def create_book(book: Book):
"""
新增一本書籍,回傳儲存後的資料。
"""
# 這裡假設已寫入資料庫
return book
- Pydantic 模型的
Field參數(如example、description)會直接映射到 OpenAPI 文件,讓前端開發者一眼就能看到範例值。 response_model告訴 FastAPI 回傳資料的結構,同樣會被寫入文件。
範例 4:自訂文件資訊與全域標頭說明
app = FastAPI(
title="客戶管理系統 API",
description="""
這是一套 **客戶管理** 的 RESTful API,提供以下功能:
- 客戶資料 CRUD
- 訂單查詢
- 統計報表
""",
version="2.0.0",
terms_of_service="https://example.com/terms/",
contact={
"name": "技術支援團隊",
"url": "https://example.com/support",
"email": "support@example.com",
},
license_info={"name": "MIT License", "url": "https://opensource.org/licenses/MIT"},
)
@app.get("/customers/{customer_id}", tags=["Customers"])
def get_customer(customer_id: int):
"""取得客戶資料"""
return {"id": customer_id, "name": "張三"}
tags參數可以把路由歸類,UI 上會出現分組標籤,提升文件可讀性。description支援 Markdown,粗體、斜體、程式碼區塊皆可直接呈現在 UI。
範例 5:加入 OAuth2 安全機制,文件自動顯示授權流程
from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
app = FastAPI(title="安全 API 範例")
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/token")
@app.post("/token")
def login(form_data: OAuth2PasswordRequestForm = Depends()):
"""
取得 JWT token(此範例僅示意,不包含實際驗證)
"""
# 假設驗證成功後回傳 token
return {"access_token": "fake-token", "token_type": "bearer"}
def fake_decode_token(token: str):
if token != "fake-token":
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
return {"sub": "user@example.com"}
@app.get("/secure-data")
def read_secure_data(token: str = Depends(oauth2_scheme)):
"""
需要 JWT 授權的端點
"""
user = fake_decode_token(token)
return {"user": user["sub"], "data": "這是保護的資料"}
OAuth2PasswordBearer會在 OpenAPI 中自動產生 securitySchemes,Swagger UI 會顯示「Authorize」按鈕,讓測試者先取得 token 再呼叫受保護的路由。- 若要在 ReDoc 中顯示同樣的授權流程,只要保持 OpenAPI 規範完整即可,兩者會同步更新。
常見陷阱與最佳實踐
| 陷阱 | 說明 | 解決方式 |
|---|---|---|
| 文件未同步 | 修改路由或模型卻忘記重啟伺服器(開發環境未使用 --reload) |
使用 uvicorn --reload 或在 CI/CD 中自動產生 OpenAPI JSON |
| 過度曝光內部結構 | 直接把資料庫 ORM 模型作為回傳模型,可能洩漏欄位 | 建立 專屬的 Pydantic Schema,只保留必要欄位 |
缺少 example |
UI 顯示的範例為空,使用者不易理解 | 在 Field(..., example=...) 或 response_model_exclude_unset 中提供範例 |
未設定 tags |
大型專案 UI 變得雜亂 | 為每個功能區塊加上 tags=["User", "Item"],提升文件可讀性 |
| 安全機制未同步 | OAuth2、API Key 等設定寫在程式碼,但未在 OpenAPI 中宣告 | 使用 FastAPI 提供的 Security、APIKeyHeader 等類別,自動產生 securitySchemes |
最佳實踐:
- 始終提供
example:不論是請求體、回傳模型或參數,都給出具體範例。 - 分層 Schema:建立
CreateX,UpdateX,ReadX等不同 Pydantic 類別,讓文件更清晰。 - 使用
tags與summary:在路由裝飾器中加入tags、summary、description,讓 UI 自動生成目錄與說明。 - 自動產生 OpenAPI JSON:在 CI 流程中執行
python -c "import json, fastapi; ..."或使用fastapi-cli產出openapi.json,放入版本控制。 - 保護文件路徑:在正式環境可把
/docs、/redoc設為僅內部可訪問,或使用FastAPI(..., docs_url=None, redoc_url=None),自行部署專屬的 API 文件平台(如 SwaggerHub)。
實際應用場景
微服務間契約測試
每個微服務在部署時自動產出openapi.json,CI 內部使用schemathesis或prance進行契約測試,確保介面不破壞相容性。前端自動生成 API 客戶端
利用openapi-generator讀取 FastAPI 產出的規格,產生 TypeScript、JavaScript、Swift 等語言的 SDK,減少手寫 API 呼叫的錯誤。對外合作夥伴文件
只要把/redoc的 URL 或產出的openapi.json提供給合作夥伴,即可讓他們快速了解授權方式、參數限制,縮短對接時間。內部知識庫
把redoc產出的 HTML 靜態檔案嵌入 Confluence、SharePoint 或內部 Wiki,讓非技術人員也能查閱 API 功能。安全稽核
透過 OpenAPI 中的securitySchemes,稽核團隊可以快速列出所有受保護的端點,檢查是否符合公司資訊安全政策。
總結
FastAPI 以 零設定 的方式把 OpenAPI 規範內嵌於框架核心,開發者只要專注於路由與資料模型,文件就會自動、即時地以 Swagger UI (/docs) 與 ReDoc (/redoc) 兩種風格呈現。
透過本文的五個實作範例,你可以:
- 建立最小可用的 API 文件
- 在路由、參數、回傳模型上加入說明與範例
- 自訂 API 標題、版本、聯絡資訊,讓文件更具專業度
- 加入 OAuth2 等安全機制,讓 UI 能直接測試授權流程
- 避免常見的文件不同步、資訊過度曝光等陷阱,並遵循最佳實踐提升可維護性
在實務上,將 自動產生的 OpenAPI 文件 作為開發、測試、合作與安全稽核的共同語言,能顯著縮短開發週期、降低溝通成本,讓你的服務在快速迭代的同時仍保持高品質與一致性。快把這些技巧落實到你的下一個 FastAPI 專案,讓 API 從「黑盒子」變成「可見、可測、可管理」的資產吧!