Ответ
Dependency Injection (DI) в FastAPI — это мощный механизм, который позволяет декларативно определять и внедрять зависимости (компоненты, ресурсы, сервисы) в функции обработчиков маршрутов (endpoints).
Почему это важно? DI значительно упрощает архитектуру приложения, делая код более модульным, тестируемым и поддерживаемым. Он позволяет избежать жесткой привязки компонентов и легко заменять их (например, для тестирования или использования разных конфигураций).
Как это работает?
FastAPI автоматически обнаруживает зависимости, указанные с помощью Depends()
, и разрешает их перед вызовом функции маршрута. Зависимости могут быть асинхронными функциями, генераторами или классами.
Пример с управлением ресурсами (сессия БД):
from fastapi import FastAPI, Depends, HTTPException, status
from typing import Generator
app = FastAPI()
# Имитация подключения к базе данных
def get_db_connection() -> Generator[str, None, None]:
db_session = "Connected to DB"
try:
print(f"[DB] Открываем соединение: {db_session}")
yield db_session # Передаем сессию в обработчик маршрута
finally:
print(f"[DB] Закрываем соединение: {db_session}")
# Здесь обычно происходит закрытие соединения с БД
@app.get("/items/")
def read_items(db: str = Depends(get_db_connection)):
"""Получение списка элементов, используя зависимость от БД."""
if not db:
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="DB connection failed")
return {"message": f"Используем: {db} для получения элементов"}
@app.get("/users/")
def read_users(db: str = Depends(get_db_connection)):
"""Получение списка пользователей, используя ту же зависимость."""
return {"message": f"Используем: {db} для получения пользователей"}
Ключевые преимущества:
- Переиспользование кода: Одна зависимость может быть использована в множестве маршрутов.
- Тестируемость: Легко подменять реальные зависимости "моками" в тестах, изолируя тестируемый код.
- Управление ресурсами: Генераторы с
yield
иtry...finally
идеально подходят для управления жизненным циклом ресурсов (открытие/закрытие соединений, транзакций). - Чистота кода: Логика обработчика маршрута остается сфокусированной на своей основной задаче, а не на получении зависимостей.
- Каскадные зависимости: Зависимости могут зависеть от других зависимостей, создавая цепочки.