FastAPI Dependency Injection: Depends() and yield Context Cleanup
- Last updated
- Prerequisites:
- Python Generators (`yield`)
- FastAPI route handler basics
- fastapi
- dependency-injection
- depends
- yield
- cleanup
- database-session
Read at your depth
The practical view
FastAPI uses `Depends()` to inject shared dependencies into route handlers: `def get_db(): db = Session(); try: yield db; finally: db.close()`. In your endpoint: `@app.get('/users') def list_users(db: Session = Depends(get_db)): ...`. The code before `yield` runs before the route handler, and the code after `yield` (or inside `finally`) is guaranteed to run after the response is sent, ensuring safe resource cleanup.
The same idea in other frameworks
`db: Session = Depends(get_db)` with `yield db` in generator.NestJS Request-scoped provider with `OnModuleDestroy` or `custom providers`.Spring `@Transactional` / `PersistenceContext` session management.Express middleware attaching `req.db` and listening to `res.on('finish')`.Legacy vs modern
Manual Try/Finally DB Connection vs FastAPI yield Dependency
Manual session management in every route leaks connections on unhandled errors; `Depends()` with `yield` guarantees clean teardown.
db = Session(); try: ... finally: db.close(); // ❌ Boilerplate in every route handlerdef get_db(): db = SessionLocal(); try: yield db; finally: db.close(); // ✅ NEW: Auto-cleanupInterview gotchas
Context
Interviewers test your knowledge of dependency memoization within a single request lifecycle.
The mechanical answer
`use_cache=True` ensures that if a dependency function (e.g. `get_current_user` or `get_db`) is referenced multiple times across sub-dependencies within the same request, **FastAPI executes the dependency function only once** and caches its result for the duration of that specific request. If you need a dependency to execute a fresh calculation every time it is injected, set `Depends(my_func, use_cache=False)`.
Trap
The cache is request-scoped; it never persists or leaks data across different HTTP requests.
Context
Checks understanding of error propagation in generator dependencies.
The mechanical answer
FastAPI propagates the exception into the generator using `generator.throw(exception)`. If you have a `try...finally:` block around your `yield`, the `finally:` block is **guaranteed to execute**, ensuring database sessions close or transactions roll back even when an HTTP 500 error occurs.
Trap
If you catch the exception inside the dependency (`except Exception:`) and do not re-raise it, you will accidentally swallow the route handler's exception.