Как работает механизм Dependency Injection в FastAPI с помощью `Depends`?

Ответ

Механизм Dependency Injection (DI) в FastAPI позволяет объявлять зависимости, которые должны быть выполнены перед вызовом функции-обработчика эндпоинта. FastAPI автоматически разрешает эти зависимости и передает их результаты в качестве аргументов. Основным инструментом для этого является Depends.

Принцип работы:

  1. Вы объявляете функцию-зависимость (dependency function).
  2. В функции-обработчике маршрута вы указываете эту зависимость в аннотации типа аргумента, используя Depends(dependency_function).
  3. Перед тем как вызвать ваш обработчик, FastAPI вызовет функцию-зависимость.
  4. Результат, возвращенный зависимостью, будет передан в ваш обработчик в качестве значения соответствующего аргумента.

Пример: Управление сессией базы данных

Классический пример — получение сессии БД, её использование в запросе и гарантированное закрытие после завершения.

from fastapi import FastAPI, Depends
from sqlalchemy.orm import Session

# Представим, что эти функции управляют сессией БД
from .database import SessionLocal

app = FastAPI()

# 1. Функция-зависимость
def get_db_session():
    db = SessionLocal()
    try:
        # yield передает управление и значение (сессию)
        yield db
    finally:
        # Этот код выполнится после завершения запроса
        db.close()

@app.get("/items/{item_id}")
# 2. Использование Depends для внедрения зависимости
async def read_item(item_id: int, db: Session = Depends(get_db_session)):
    # 3. FastAPI передает результат get_db_session в аргумент `db`
    item = db.query(Item).filter(Item.id == item_id).first()
    return item

Ключевые преимущества:

  • Повторное использование кода: Общую логику (аутентификация, подключение к БД) можно вынести в зависимости и использовать в разных эндпоинтах.
  • Управление ресурсами: Использование yield в зависимостях-генераторах позволяет выполнять код до и после обработки запроса (например, открытие и закрытие транзакций).
  • Упрощение тестирования: Зависимости легко подменить (mock) во время тестов, что позволяет изолировать тестируемый код.
  • Иерархия зависимостей: Зависимости могут зависеть от других зависимостей, создавая граф вычислений.