Проект на FastAPI вырос из MVP в большой production-сервис. Какие проблемы архитектуры и сопровождения вы ожидаете увидеть?
Рост FastAPI-проекта обнажает монолитную структуру, бизнес-логику в endpoint-ах, отсутствие версионирования API, hardcoded конфиг и нехватку тестов. Решение — ранняя модульная структура с service layer, DI и миграциями.
Типичный путь от MVP к production
MVP-проект на FastAPI обычно стартует как один файл main.py со всеми роутами, моделями и бизнес-логикой вместе. При росте это превращается в набор взаимосвязанных проблем.
Архитектурные проблемы
- Монолитный main.py — 2000+ строк в одном файле, circular imports при попытке разделить. Решение: APIRouter по доменам, каждый роутер в своём пакете.
- Бизнес-логика в endpoints — SQL-запросы, сложные вычисления и отправка email прямо в функции endpoint. При росте невозможно тестировать и переиспользовать. Нужен слой сервисов (service layer).
- God-объект Session/DB — один глобальный объект сессии используется везде; конкурентные запросы конфликтуют. Нужен DI через
Depends(get_db)с per-request сессиями. - Отсутствие версионирования API — изменение контракта ломает всех клиентов. Вводите
/api/v1/с самого начала.
Проблемы сопровождения
- Дублирование Pydantic-схем — одна и та же модель описана 5 раз (Create, Update, Response, DB, Internal). Нужна иерархия схем с наследованием.
- Hardcoded конфиг — URL БД, секреты, feature flags прямо в коде. При смене окружения приходится редактировать исходники.
- Нет миграционной стратегии — Alembic добавляется поздно, первые миграции созданы вручную и содержат ошибки; накопленный migration history не воспроизводится с нуля.
Рекомендуемая структура для большого проекта
app/
api/
v1/
users.py
orders.py
core/
config.py # BaseSettings
security.py
database.py
models/ # SQLAlchemy ORM
schemas/ # Pydantic
services/ # бизнес-логика
repositories/ # слой доступа к данным
worker/ # Celery/ARQ задачи
main.py
alembic/
tests/
Observability как запоздалая мысль
В MVP нет логов, метрик и трейсинга. При первом инциденте в production невозможно понять что произошло. Добавляйте prometheus-fastapi-instrumentator и structlog как можно раньше — они требуют минимальных усилий.
Тестирование
MVP часто вообще без тестов. При рефакторинге монолитного кода без тестов каждое изменение — рулетка. Минимум: pytest + httpx.AsyncClient для интеграционных тестов API, отдельная тестовая БД через pytest-asyncio.
import pytest
from httpx import AsyncClient, ASGITransport
from main import app
@pytest.mark.asyncio
async def test_create_user():
async with AsyncClient(
transport=ASGITransport(app=app),
base_url="http://test"
) as client:
resp = await client.post("/api/v1/users", json={"email": "a@b.com"})
assert resp.status_code == 201
Подводные камни
- Преждевременная микросервисная декомпозиция — разбивать MVP на 10 сервисов на старте убивает скорость; сначала модульный монолит, потом выделение сервисов по нагрузке.
- Нет контракта API — изменение схемы ответа без версионирования ломает мобильные клиенты, которые не обновляются синхронно.
- Alembic autogenerate доверяют слепо — autogenerate не замечает изменений в
CheckConstraint, индексах с условиями, sequences; всегда проверяйте сгенерированный файл вручную. - Глобальный state в app.state — удобно для MVP, но при нескольких воркерах каждый имеет свою копию state; для shared state нужен Redis.
- Dependency hell при росте — цепочки из 10 вложенных Depends трудно читать и тестировать; группируйте в dataclass-зависимости или используйте фабрики.
- Swagger как единственная документация — auto-generated OpenAPI хорош для старта, но при сложном API нужны примеры, руководства и changelog.
What hurts your answer
- Говорить только о запуске FastAPI, но не об эксплуатации
- Не упоминать observability, обновления, безопасность и rollback
- Описывать риски абстрактно, без способов их снижать
What they're listening for
- Видит production-риски FastAPI
- Говорит про monitoring, rollout, rollback и безопасность
- Умеет ранжировать риски по вероятности и влиянию