Опыт разработки маркетплейса LuchMarket на Symfony с нуля: архитектурные решения, которые оправдались, и то, что я бы сделал иначе.
Что я понял, сделав маркетплейс с нуля без заказчика
LuchMarket я начинал без технического задания, без дедлайна и без клиента, который будет недоволен, если что-то пойдёт не так. Это одновременно и преимущество, и ловушка, потому что без внешнего давления очень легко бесконечно долго полировать то, что никто кроме тебя никогда не увидит.
Выбор Symfony для этой задачи был осознанным, а не случайным. До этого девять лет я писал на Perl в высоконагруженном e-commerce, и мне было интересно собрать похожую по смыслу систему на совсем другом стеке, чтобы сравнить не на словах, а на практике, где архитектурные решения переносятся между экосистемами, а где нет. Оказалось, что переносится на удивление много: подход к разделению слоёв, к очередям фоновых задач, к кэшированию часто запрашиваемых данных про товары и категории. Не переносится специфика самого языка и экосистемы, в Symfony куда больше готовых компонентов из коробки, и соблазн тащить очередной бандл вместо того, чтобы написать тридцать строк самому, встречается постоянно.
Самое полезное архитектурное решение, которое я бы повторил снова, это разделение каталога товаров и логики заказов на разные модули с чётко определённым контрактом между ними с самого начала, даже когда проект маленький и кажется, что можно обойтись одним большим контроллером. Маркетплейс по своей природе быстро обрастает исключениями: товары с вариациями, многошаговое оформление заказа, разные способы доставки, скидки и промокоды, которые взаимодействуют друг с другом не всегда очевидным образом. Если с первого дня не провести границу между «что такое товар» и «что происходит, когда его покупают», эта граница потом размывается так, что переделывать больно.
Что бы я сделал иначе, если бы начинал сейчас. Я бы раньше ввёл события вместо прямых вызовов между модулями, сейчас в паре мест каталог напрямую знает о внутренностях модуля заказов, и это ровно то сцепление, которое я сам пытался избежать в начале, но не удержал дисциплину до конца. Ещё бы раньше настроил нагрузочное тестирование критичных путей, оформление заказа и поиск по каталогу, потому что на реальном трафике узкие места почти никогда не там, где их ожидаешь увидеть, глядя в код.
Разработка собственного продукта с нуля, без заказчика, который постоянно меняет требования, дала мне то, что сложно получить на обычном проекте: возможность довести архитектурное решение до конца и честно увидеть, где оно развалилось не из-за внешних обстоятельств, а из-за моих собственных решений на старте. Это полезнее любого курса по архитектуре, потому что ошибки тут свои, а не чужие, и их приходится чинить самому. Если нужен похожий проект с нуля, разработку MVP я тоже делаю, подробности здесь.