Какой архитектурный подход используется в FastAPI?

Ответ

FastAPI не навязывает строгий архитектурный паттерн, но его дизайн естественным образом способствует организации кода по принципам, схожим с Model-View-Controller (MVC), с сильным акцентом на Dependency Injection (DI).

Основные компоненты можно соотнести так:

  • Модели (Model): Определяются с помощью Pydantic для валидации и сериализации данных (входящих запросов и исходящих ответов). Для работы с базой данных используются ORM (например, SQLAlchemy, Tortoise ORM), которые также представляют собой модели.
  • Представления (View): В FastAPI это функции-обработчики маршрутов (path operation functions), декорированные @app.get, @app.post и т.д. Они отвечают за обработку HTTP-запросов, вызов бизнес-логики и формирование HTTP-ответов.
  • Контроллеры (Controller): Бизнес-логика, которая может быть инкапсулирована в отдельные функции или классы и вызываться из функций-обработчиков. FastAPI поощряет вынесение сложной логики в отдельные модули для чистоты и тестируемости.

Dependency Injection (DI) является ключевой особенностью FastAPI. Она позволяет:

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

Пример:

from fastapi import FastAPI, Depends
from pydantic import BaseModel

app = FastAPI()

# Model (Pydantic)
class Item(BaseModel):
    name: str
    price: float

# Dependency (DI) - имитация получения ресурса (например, сессии БД)
def get_db():
    """Имитирует получение сессии базы данных."""
    return "fake_db_session_123"

# View/Controller (Path Operation Function)
@app.post("/items/")
def create_item(item: Item, db: str = Depends(get_db)):
    """
    Создает новый товар, используя внедренную зависимость.
    """
    # Здесь могла бы быть бизнес-логика сохранения item в БД
    return {"item": item, "db_session": db}

Такой подход делает код модульным, легко тестируемым, расширяемым и способствует созданию чистых API.