基本的なDependsを超えて、FastAPIの依存性注入は以下の高度なパターンをサポートしています:サブ依存性、パラメータ付き依存性(クラスベースまたはファクトリ経由)、スコープ付きリソース(yield)、グローバル/ルータレベルの依存性、およびテスト用の依存性オーバーライド — これにより、実アプリケーションを構造化するための多目的なツールとなります。
def get_token(authorization: str = Header()):
return parse(authorization)
def get_current_user(token: str = Depends(get_token)): # depends on another dependency
return decode(token)
def get_admin(user: User = Depends(get_current_user)): # depends on that, in turn
if not user.is_admin: raise HTTPException(403)
return user
# FastAPI resolves the whole chain, caching shared dependencies within a request
依存性は他の依存性に依存することができ、FastAPIが自動的に解決するツリーを形成します(そして共有されるものはリクエストごとにキャッシュされるため、複数の依存性で使用されてもget_tokenは一度だけ実行されます)。
class RateLimiter:
def __init__(self, calls: int): # configure the dependency
self.calls = calls
def __call__(self, request: Request): # callable → acts as a dependency
check_rate_limit(request, self.calls)
@app.get("/items", dependencies=[Depends(RateLimiter(calls=100))]) # configured per route
def items(): ...
__call__を持つクラスは設定可能な依存性です — 使用時にパラメータ化します(例:ルートごとに異なるレート制限)。
@app.get("/admin", dependencies=[Depends(verify_admin)]) # run for the effect (auth check)
def admin(): ... # don't need its return value
app = FastAPI(dependencies=[Depends(verify_api_key)]) # applies to EVERY route
router = APIRouter(dependencies=[Depends(get_current_user)]) # to all routes in a router
アプリケーション全体またはルータごとに依存性を適用して、横断的な要件(認証、レート制限)に対応します。
app.dependency_overrides[get_db] = get_test_db # swap any dependency in tests
FastAPIの依存性注入はその最も強力な機能の1つであり、これらの高度なパターンが実際の複雑なアプリケーションをエレガントに構造化することを可能にします。
これらを理解することはシニアレベルの価値のある知識です:サブ依存性は再利用可能なレイヤー(トークン → ユーザー → 管理者)を構築し、自動解決とリクエストごとのキャッシングで冗長な処理を避けます;パラメータ化/クラスベースの依存性は設定可能で再利用可能なコンポーネント(レート制限、ルートごとに異なる設定の権限チェック)を作成します;副作用としての依存性は関数シグネチャを複雑にすることなく要件(認証)をきれいに強制します;そしてグローバル/ルータレベルの依存性は横断的な関心事(認証、レート制限)をルートグループ全体に1箇所で適用します。
重要なことに、依存性オーバーライドにより、複雑な依存性グラフでもテストが簡単になります。
これらのパターンをマスターする — 依存性を合成し、パラメータ化し、グローバルまたはルータごとにスコープ化し、テストでオーバーライドする — ことは、非自明なFastAPIアプリケーションでクリーンで、DRYで、テスト可能なアーキテクチャを実現する方法であり、フレームワークのDIシステムを完全に活用できる開発者とシンプルなDependsのみを使う開発者を区別します。
これは、構造が良く、保守性の高い、大規模なFastAPIアプリケーションを構築するための重要なトピックです。