本文 AI 產出,尚未審核

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() 物件時傳入 titledescriptionversionterms_of_servicecontactlicense_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 參數(如 exampledescription)會直接映射到 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 提供的 SecurityAPIKeyHeader 等類別,自動產生 securitySchemes

最佳實踐

  1. 始終提供 example:不論是請求體、回傳模型或參數,都給出具體範例。
  2. 分層 Schema:建立 CreateX, UpdateX, ReadX 等不同 Pydantic 類別,讓文件更清晰。
  3. 使用 tagssummary:在路由裝飾器中加入 tagssummarydescription,讓 UI 自動生成目錄與說明。
  4. 自動產生 OpenAPI JSON:在 CI 流程中執行 python -c "import json, fastapi; ..." 或使用 fastapi-cli 產出 openapi.json,放入版本控制。
  5. 保護文件路徑:在正式環境可把 /docs/redoc 設為僅內部可訪問,或使用 FastAPI(..., docs_url=None, redoc_url=None),自行部署專屬的 API 文件平台(如 SwaggerHub)。

實際應用場景

  1. 微服務間契約測試
    每個微服務在部署時自動產出 openapi.json,CI 內部使用 schemathesisprance 進行契約測試,確保介面不破壞相容性。

  2. 前端自動生成 API 客戶端
    利用 openapi-generator 讀取 FastAPI 產出的規格,產生 TypeScript、JavaScript、Swift 等語言的 SDK,減少手寫 API 呼叫的錯誤。

  3. 對外合作夥伴文件
    只要把 /redoc 的 URL 或產出的 openapi.json 提供給合作夥伴,即可讓他們快速了解授權方式、參數限制,縮短對接時間。

  4. 內部知識庫
    redoc 產出的 HTML 靜態檔案嵌入 Confluence、SharePoint 或內部 Wiki,讓非技術人員也能查閱 API 功能。

  5. 安全稽核
    透過 OpenAPI 中的 securitySchemes,稽核團隊可以快速列出所有受保護的端點,檢查是否符合公司資訊安全政策。


總結

FastAPI 以 零設定 的方式把 OpenAPI 規範內嵌於框架核心,開發者只要專注於路由與資料模型,文件就會自動、即時地以 Swagger UI (/docs) 與 ReDoc (/redoc) 兩種風格呈現。
透過本文的五個實作範例,你可以:

  • 建立最小可用的 API 文件
  • 在路由、參數、回傳模型上加入說明與範例
  • 自訂 API 標題、版本、聯絡資訊,讓文件更具專業度
  • 加入 OAuth2 等安全機制,讓 UI 能直接測試授權流程
  • 避免常見的文件不同步、資訊過度曝光等陷阱,並遵循最佳實踐提升可維護性

在實務上,將 自動產生的 OpenAPI 文件 作為開發、測試、合作與安全稽核的共同語言,能顯著縮短開發週期、降低溝通成本,讓你的服務在快速迭代的同時仍保持高品質與一致性。快把這些技巧落實到你的下一個 FastAPI 專案,讓 API 從「黑盒子」變成「可見、可測、可管理」的資產吧!