FASTAPI / 4. DEPENDENCY INJECTION
Dependency Injection
The most powerful FastAPI feature — clean, reusable, testable logic
EXPLANATION
Dependency Injection (DI) is FastAPI's most elegant feature. Instead of repeating logic (auth checks, DB sessions, pagination params) in every route, you define it once as a dependency and inject it wherever needed. How it works: • Define a function (sync or async) that returns something useful • Declare it as a parameter type-hinted with Depends(your_function) • FastAPI calls it automatically before your route, passes the result in Dependencies can themselves have dependencies — you build a dependency tree. FastAPI resolves the whole tree before calling your route. This is exactly like constructor injection in Java/C# but Pythonic. Common use cases: ① Pagination parameters — extract skip/limit once, reuse everywhere ② Database sessions — open a session, yield it, always close it (generator pattern) ③ Authentication — verify JWT token, return current user ④ Permission checks — "current user must be admin" ⑤ Rate limiting, logging, feature flags Yield dependencies (yield instead of return) are the pattern for resources that need cleanup. Code before yield = setup, code after yield = teardown. FastAPI handles this like a context manager — teardown always runs, even on exceptions. Dependencies can be added at route level, router level, or app level. App-level dependencies run on every single request. Sub-dependencies compose naturally: get_db → get_current_user → require_admin Each layer builds on the last. FastAPI caches each dependency's result within a single request so get_db is only called once even if multiple route params need it.
ARCHITECTURE
@app.get("/admin/dashboard")
def dashboard(admin: User = Depends(require_admin)):
│
┌──────────────────────────────┘
↓ require_admin calls:
get_current_user(token)
│
↓ get_current_user calls:
get_db() + oauth2_scheme()
│
↓
DB Session + JWT Token
FastAPI resolves BOTTOM UP:
1. get_db() → db session
2. oauth2_scheme() → JWT string from header
3. get_current_user(db, token) → User object
4. require_admin(user) → User if admin, else 403
5. dashboard(admin) → response
All cached per-request. get_db() called only once.CODE