FastAPI 全域依賴與 APIRouter 依賴

有時候,你希望某個依賴項能應用到所有的路徑操作,或者是一整組的路徑,而不需要在每個函數上都寫一遍 Depends(...)

例如:

  • 驗證每個請求都包含特定的 API Key header。
  • 記錄每個請求的 Log。

在路徑裝飾器中加入依賴

如果你只需要在某個特定的路徑執行依賴,但不需要它的回傳值,你可以把 Depends 加在 @app.get(...) 裝飾器的 dependencies 參數中。

from typing import Annotated
from fastapi import FastAPI, Depends, Header, HTTPException

app = FastAPI()

async def verify_token(x_token: Annotated[str, Header()]):
    if x_token != "fake-super-secret-token":
        raise HTTPException(status_code=400, detail="X-Token header invalid")

async def verify_key(x_key: Annotated[str, Header()]):
    if x_key != "fake-super-secret-key":
        raise HTTPException(status_code=400, detail="X-Key header invalid")

@app.get("/items/", dependencies=[Depends(verify_token), Depends(verify_key)])
async def read_items():
    return [{"item": "Foo"}, {"item": "Bar"}]

這個 read_items 函數在執行前,會先執行 verify_tokenverify_key。如果其中任何一個拋出例外 (如 HTTPException),這個請求就會中止,不會執行到 read_items

全域依賴 (Global Dependencies)

如果你希望整個應用程式的所有路由都套用某些依賴,可以在建立 FastAPI 實例時設定 dependencies 參數。

app = FastAPI(dependencies=[Depends(verify_token), Depends(verify_key)])

@app.get("/items/")
async def read_items():
    # 這個路由會自動受到 verify_token 和 verify_key 的保護
    return [{"item": "Portal Gun"}, {"item": "Plumbus"}]

@app.get("/users/")
async def read_users():
    # 這個路由也會!
    return [{"username": "Rick"}, {"username": "Morty"}]

APIRouter 的依賴

如果你使用 APIRouter 來組織大型專案 (我們稍後會在專案結構章節詳細介紹),你也可以為特定的 Router 設定依賴。

from fastapi import APIRouter

router = APIRouter(
    prefix="/users",
    tags=["users"],
    dependencies=[Depends(verify_token)], # 所有 /users 下的路由都要驗證 token
)

總結

  • Decorators: 使用 dependencies=[Depends(...)] 在路徑裝飾器中添加不回傳值的依賴。
  • Global: 在 FastAPI(...) 中添加依賴,影響所有路由。
  • Router: 在 APIRouter(...) 中添加依賴,影響該 Router 下的所有路由。
  • 這是一種實作全域驗證、Logging 或權限控管的絕佳方式。