API‑first – это принцип проектирования, при котором публичный интерфейс определён ещё до написания бизнес‑логики. Такой подход позволяет согласовать контракты между командами, автоматизировать тестирование и упростить миграцию между технологиями.
Контрактное описание: OpenAPI vs. Symfony API Platform
Для API‑first критически важен формальный контракт. На Python‑стеке наиболее распространён OpenAPI 3.0, а в PHP‑сообществе – API Platform, который генерирует OpenAPI из аннотаций.
- OpenAPI‑first (FastAPI). Схема описывается в YAML/JSON и импортируется в FastAPI через
APIRouter. Позволяет использоватьpydanticмодели как единственный источник правды. - Code‑first (Symfony API Platform). Аннотации в сущностях (
@ApiResource) автоматически генерируютOpenAPI. Удобно, когда бизнес‑логика уже реализована в Doctrine‑моделях.
Архитектурные слои
Независимо от стека, рекомендуется разделять слои:
- Transport – роутинг, сериализация, десериализация.
- Application – сервисы, use‑case классы, бизнес‑правила.
- Domain – чистые модели, Value Objects, сущности.
- Infrastructure – репозитории, внешние API, кеш.
Такой Clean Architecture позволяет менять транспортный слой (FastAPI ↔ Symfony) без затрагивания бизнес‑логики.
FastAPI: реализация транспортного слоя
FastAPI использует Starlette под капотом, что даёт асинхронный I/O без дополнительной конфигурации. Пример роутера, построенного по контракту:
from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel
from typing import List
router = APIRouter(prefix="/v1/books", tags=["books"])
class BookIn(BaseModel):
title: str
author: str
pages: int
class BookOut(BookIn):
id: int
@router.post("/", response_model=BookOut, status_code=201)
async def create_book(payload: BookIn, service: BookService = Depends()):
try:
return await service.create(payload)
except DuplicateTitleError as exc:
raise HTTPException(status_code=409, detail=str(exc))
@router.get("/", response_model=List[BookOut])
async def list_books(service: BookService = Depends()):
return await service.list()
Здесь BookService – слой Application, а BookIn/BookOut – единственный источник правды, генерируемый из OpenAPI схемы.
Symfony + API Platform: транспортный слой
API Platform создаёт роуты, сериализаторы и валидацию из атрибутов/аннотаций. Пример сущности:
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
#[ApiResource(
collectionOperations: [
'get' => ['normalization_context' => ['groups' => ['book:read']]],
'post' => ['denormalization_context' => ['groups' => ['book:write']]]
],
itemOperations: ['get', 'put', 'delete']
)]
class Book
{
#[ORM\Id, ORM\GeneratedValue, ORM\Column(type: 'integer')]
private int $id;
#[ORM\Column(type: 'string')]
private string $title;
#[ORM\Column(type: 'string')]
private string $author;
#[ORM\Column(type: 'integer')]
private int $pages;
// getters & setters …
}
API Platform автоматически генерирует OpenAPI, поддерживает JSON:API и Hydra. При необходимости можно переопределить контроллер, внедрив сервис из Application‑слоя.
Кросс‑стек интеграция: микросервисы и шлюз API‑gateway
Для гибкой архитектуры часто используют отдельные микросервисы на разных языках. Пример схемы:
- FastAPI‑service – тяжелый аналитический модуль, работающий с
asyncioиRedis. - Symfony‑service – CRUD‑операции над бизнес‑объектами, использующий Doctrine и Symfony Messenger.
- API‑gateway (Kong/Nginx) – единая точка входа, маршрутизирует запросы по
OpenAPIспецификации.
Такой набор позволяет масштабировать отдельные части без полного переезда.
Оптимизация производительности
- Асинхронность. FastAPI использует
async def, что уменьшает время простоя при I/O‑операциях (DB, внешние сервисы). Symfony 6 поддерживаетasyncконтроллеры черезSymfony Runtime, но экосистема (Doctrine) остаётся синхронной, требуя отдельные адаптеры (Doctrine Async). - Кеширование. В обоих стеках рекомендуется использовать
Cache‑Asideпаттерн. FastAPI часто интегрируетaioredis, Symfony –symfony/cacheс тегированными кешами. - Батчинг запросов. При необходимости собрать данные из нескольких микросервисов, используйте
GraphQLслой (Apollo Server) илиBatching middlewareв FastAPI (httpx.AsyncClient). - Тестирование контрактов. Инструменты
schemathesis(FastAPI) иAPI Platform Testпозволяют генерировать тесты из OpenAPI, гарантируя обратную совместимость.
Сравнительная таблица
+----------------------+--------------------------+--------------------------+
| Feature | FastAPI (Python) | Symfony + API Platform |
+----------------------+--------------------------+--------------------------+
| Language | Python 3.9+ (type hints) | PHP 8.2+ |
| Primary paradigm | async / function based | annotations / attributes |
| OpenAPI generation | from schema (code‑first) | from annotations (code‑first) |
| Validation library | pydantic (runtime) | Symfony Validator |
| ORM integration | SQLModel / Tortoise ORM | Doctrine ORM |
| Async DB support | native (asyncpg) | experimental (Doctrine Async) |
| Auto‑docs UI | Swagger UI / ReDoc | Swagger UI (API Platform) |
| Extensibility | Depends, middleware | EventSubscriber, DataProvider |
| Community & plugins | Starlette ecosystem | Symfony bundles |
+----------------------+--------------------------+--------------------------+
Выбор стека
Если проект требует высокой конкурентности, интенсивных I/O‑операций и лёгкой интеграции с ML‑моделями, FastAPI будет предпочтительным. Если уже есть зрелая PHP‑инфраструктура, сложные бизнес‑правила, а также необходимость в богатой экосистеме (Messenger, Security, Twig), Symfony + API Platform даст более быстрый старт.
Заключение
API‑first – фундамент для гибкой, масштабируемой архитектуры. Чётко разделяя слои, используя OpenAPI как единый контракт и выбирая подходящий транспортный стек (FastAPI или Symfony), можно построить систему, готовую к микросервисному росту, асинхронной нагрузке и удобному тестированию.
Сложные веб‑проекты, требующие продуманной архитектуры, высокой производительности и грамотного выбора технологий, можно заказать у Усачёва Дениса (RybinskLab).