依賴注入
依賴注入(dependency injection)的意思是:路徑操作函式不自己建立「它需要的東西」,而是宣告「我需要這個」,由 FastAPI 在呼叫前準備好。資料庫 session、目前登入使用者、共用的查詢參數,都該走這條路。
最簡單的 Depends
from typing import Annotated
from fastapi import Depends, FastAPI
app = FastAPI()
def common_parameters(skip: int = 0, limit: int = 100, q: str | None = None):
return {"skip": skip, "limit": limit, "q": q}
@app.get("/items/")
def read_items(commons: Annotated[dict, Depends(common_parameters)]):
return commons
common_parameters 本身也是一般函式,參數一樣會被當成查詢參數。多個端點都能 Depends(common_parameters),文件與驗證不會漏掉。
依賴可以再依賴別的依賴,形成樹狀結構。框架會快取同一請求內相同的依賴,避免重複查資料庫或重複解析 token。
為什麼這比「在函式裡直接連資料庫」重要
把連線寫死在路徑函式裡,測試時只能連真的資料庫,認證邏輯也會複製到每個端點。改成依賴之後:
- 路徑函式只處理業務
- 測試可用
app.dependency_overrides換成假物件(見 測試) - 認證只要寫一個
get_current_user,需要登入的端點都Depends它
使用 yield 可以在回應後清理資源:
路徑函式拿到 db,請求結束後(含例外)會執行 finally。這是 SQLAlchemy session 的標準寫法。
類別當依賴
邏輯變多時,用類別比越寫越長的函式清楚:
class Pagination:
def __init__(self, skip: int = 0, limit: int = 20):
self.skip = skip
self.limit = min(limit, 100)
然後 Depends(Pagination)。FastAPI 會把查詢參數傳進 __init__。
先掌握「函式依賴 + yield + 測試時覆寫」,就覆蓋了大多數專案。OAuth2 的 get_current_user 只是同一模式再加安全性。