FastAPI 子依賴 (Sub-dependencies)
FastAPI 的依賴注入系統非常強大,它支援建立「依賴關係圖 (Dependency Graph)」。這意味著,一個依賴項本身也可以有其他的依賴項。
FastAPI 會自動解析這些層層疊疊的關係,找出正確的執行順序。
建立子依賴
假設我們有以下需求:
- 有一個
query_extractor依賴,負責解析查詢參數q。 - 有一個
query_or_cookie_extractor依賴,它需要用到query_extractor的結果,並且可能還會讀取 Cookie。
from typing import Annotated
app = FastAPI()
# 第一層依賴
def query_extractor(q: str | None = None):
return q
# 第二層依賴:它依賴於 query_extractor
def query_or_cookie_extractor(
q: Annotated[str, Depends(query_extractor)], # 這裡注入了第一層依賴
last_query: Annotated[str | None, Cookie()] = None,
):
if not q:
return last_query
return q
# 路徑操作:它依賴於第二層依賴
@app.get("/items/")
async def read_query(query_or_default: Annotated[str, Depends(query_or_cookie_extractor)]):
return {"q_or_cookie": query_or_default}
執行流程
當使用者請求 /items/ 時,FastAPI 會:
- 發現
read_query需要query_or_cookie_extractor。 - 檢查
query_or_cookie_extractor,發現它需要query_extractor。 - 執行
query_extractor:從 URL 解析q參數。 - 執行
query_or_cookie_extractor:將query_extractor的回傳值傳給它,並同時解析 Cookie。 - 執行
read_query:將query_or_cookie_extractor的回傳值傳給它。
這個過程就像剝洋蔥一樣,從最外層(或最底層)的依賴開始執行,一層層往上傳遞。
多次使用同一個依賴
如果你的依賴關係圖很複雜,同一個依賴項可能會被多個其他依賴項所使用。
例如:
- Dependency A 需要 Dependency Common
- Dependency B 需要 Dependency Common
- Path Operation 需要 Dependency A 和 Dependency B
在同一個 Request 中,FastAPI 預設只會執行 Dependency Common 一次。它會將第一次執行的結果快取起來,然後傳給 A 和 B。
這非常重要,例如當你的 Dependency Common 是「連接資料庫」時,你絕不希望每個依賴都去重新連線一次資料庫。
如果你真的希望每次依賴被注入時都重新執行該函數 (不使用快取),可以在
Depends 中設定 use_cache=False。
例如:Depends(common_parameters, use_cache=False)。總結
- 依賴項可以依賴其他的依賴項 (子依賴)。
- FastAPI 能夠自動解析任意深度的依賴樹。
- 在同一次請求中,相同的依賴預設只會執行一次 (結果會被快取與共用)。