“FastAPI features a built-in Dependency Injection system powered by Depends(). At request time, FastAPI resolves dependencies as a Directed Acyclic Graph (DAG), caches results across sub-dependencies using use_cache=True (memoization), and guarantees cleanup teardown execution (database session commits, locks) using yield generators.”
How FastAPI builds a Directed Acyclic Graph (DAG) of Depends(), memoizes sub-dependencies, and executes teardown cleanup.
from fastapi import FastAPI, Depends, HTTPException, status
from typing import AsyncGenerator
async def get_db_session() -> AsyncGenerator:
session = await DatabasePool.acquire()
try:
yield session # Injected into endpoint
await session.commit()
except Exception:
await session.rollback()
raise
finally:
await session.close() # Guaranteed cleanup!
async def get_current_user(token: str = Depends(oauth2_scheme), db = Depends(get_db_session)):
user = await db.query_user(token)
if not user:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
return userClient sends request to endpoint requiring multiple Depends() parameters
FastAPI traverses dependency tree, constructing a topological execution order DAG
Executes sub-dependencies (e.g. get_db(), get_current_user())
Memoizes return values so duplicate dependencies run exactly once per request
Executes endpoint handler
Executes post-yield code in reverse order to close database connections and release locks
Yield dependencies guarantee 100% reliable database connection pooling return, preventing connection pool exhaustion under high concurrency.