Разделяйте транспорт и бизнес-логику
HTTP-контроллер должен принять запрос, проверить формат данных и передать работу прикладному слою. Правила вроде расчёта цены, смены статуса заказа или ограничения операции лучше не прятать внутри маршрута. Тогда ту же бизнес-логику можно использовать из очереди, консольной команды или другого интерфейса без копирования.
Моделируйте зависимости явно
Сервисы не должны самостоятельно искать глобальное подключение к базе, почте или внешнему API. Зависимости удобнее передавать через конструктор и описывать интерфейсами там, где это действительно помогает. Это упрощает тестирование и делает архитектуру видимой: по сигнатуре класса понятно, от чего он зависит.
Работайте с базой через понятные границы транзакций
Несколько связанных изменений должны либо завершаться вместе, либо откатываться. Транзакцию лучше строить вокруг бизнес-операции, а не вокруг случайного набора SQL-запросов. Длительные внешние вызовы внутри транзакции опасны: они удерживают блокировки и усложняют восстановление после сбоя.
Выносите медленные операции в фон
Отправка писем, генерация файлов и часть интеграций могут выполняться через очередь. При этом обработчик должен быть устойчив к повторному запуску: сообщение может быть доставлено повторно. Полезны уникальные идентификаторы операций, журналирование и понятная политика повторных попыток.
Наблюдаемость проектируется заранее
Логи, метрики и трассировка помогают понять, что произошло в распределённом сценарии. Записывайте идентификатор запроса или операции, ключевые этапы и ошибки без утечки секретов. Система, которую невозможно диагностировать после сбоя, остаётся сложной независимо от красоты классов.
Попробуйте на практике
Спроектировать архитектуру оформления заказа.
- Разделите HTTP-запрос, прикладную операцию и работу с данными.
- Определите, какие изменения должны находиться в одной транзакции.
- Выберите операции, которые можно отправить в очередь.
- Добавьте идентификатор операции для защиты от повторного выполнения.
- Запишите, какие события и ошибки нужно логировать.
Как проверить результат. Схема удачна, если бизнес-правила можно тестировать без HTTP, повторный фоновый запуск не создаёт дублей, а сбой можно восстановить по журналу.
Частые вопросы
Нужна ли сложному PHP-проекту микросервисная архитектура?
Не обязательно. Хорошо структурированный модульный монолит часто проще и надёжнее, пока нет конкретной причины разделять сервисы.
Что важнее: паттерны или границы ответственности?
Границы ответственности. Паттерн полезен только тогда, когда уменьшает конкретную сложность.
Стоит ли переписывать старый проект целиком?
Обычно безопаснее выделять границы и улучшать наиболее проблемные участки постепенно, сохраняя работающую систему.
Самостоятельный разбор темы. Содержание конкретной обучающей программы здесь не представлено.