Learning outcomes
- Build hierarchical dependency DAGs
- Manage connection lifespans and mocks
Mental model
FastAPI's dependency injection engine constructs a Directed Acyclic Graph (DAG) of dependencies per HTTP request, solving requirements, managing resource scope, and closing yield generators upon request completion.
Theory
Dependencies declared with Depends(func) can be nested arbitrarily deep. When a dependency uses yield instead of return, FastAPI executes code before yield prior to route handler execution, injects the yielded value, and executes code after yield during response cleanup (even if an exception occurs).
from typing import AsyncGenerator
from fastapi import FastAPI, Depends
from contextlib import asynccontextmanager
@asynccontextmanager
async def lifespan(app: FastAPI):
app.state.db = {"active": True}
yield
app.state.db["active"] = False
app = FastAPI(lifespan=lifespan)
async def get_db_session() -> AsyncGenerator[dict, None]:
session = {"session_id": "tx_9942", "db": app.state.db}
try:
yield session
finally:
session["closed"] = True
@app.get("/items")
async def read_items(db=Depends(get_db_session)):
return {"status": "ok", "session": db["session_id"]}
Alternatives and trade-offs
Manual dependency instantiation leads to code duplication and tight coupling. FastAPI's app.dependency_overrides allows swapping real databases for in-memory mocks during Pytest runs seamlessly.
Failure modes and misconceptions
- Leaking resources without
finally: Failing to wrapyieldcleanup intry...finallyleaves database sessions unclosed if route handlers raise uncaught exceptions. - Global state mutation: Modifying global dependency state across concurrent requests causes race conditions.
Decision scenario
Use asynccontextmanager lifespans for global application resource pools (database pools, Redis clients). Use Depends with yield generators for per-request session isolation.
Learning outcomes
- Build composable dependency DAGs in FastAPI routes.
- Implement lifespan context managers for application lifecycle state.
- Swap production dependencies with test doubles via
dependency_overrides.
Trade-offs
FastAPI dependency injection simplifies composition and testing, but complex nested dependency graphs can make execution order harder to trace without clear logging.
Evidence assessment
Theory and decision mastery
Decision scenario
An engineering team wants to manage global Redis connection pools initialized when the API starts up and closed on shutdown.
Where should global connection pool management be implemented in FastAPI?
Primary sources
- FastAPI Framework Architecture & Dependency Injection Specification — Tiangolo, verified 2026-07-22