Dependency Injection
FastAPI использует DI почти везде: для подключения к БД, авторизации, конфига, reusable-логики. Идея — функция объявляет, что ей нужно, фреймворк это предоставляет.
Базовая форма
from fastapi import Depends
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.get("/items")
async def list_items(db: Session = Depends(get_db)):
return db.query(Item).all()yield делает из зависимости контекстный менеджер — finally сработает
гарантированно.
Цепочки и кэширование
Зависимости могут зависеть друг от друга, и в рамках одного запроса
результат кэшируется на одном yield-уровне:
flowchart TD
A[Request /items] --> B[get_current_user]
B --> C[get_db]
B --> D[get_settings]
A --> C
get_db будет вызван один раз, даже если две зависимости его запросили.
Классы как зависимости
Любой callable работает. Класс с __init__ тоже:
class Paginator:
def __init__(self, page: int = 1, size: int = 20):
self.page = page
self.size = size
@app.get("/things")
async def list_things(p: Paginator = Depends()):
...page и size автоматически станут query-параметрами.
Когда НЕ использовать DI
- Простая трансформация данных — обычная функция проще
- Зависимость нужна только в одном эндпоинте и больше нигде
- Побочный эффект, не относящийся к запросу (используй lifespan)
Связанные заметки
- Routing & Endpoints
- Testing with httpx —
app.dependency_overrides