Дорогое архитектурное решение обычно — переписывание, которое никому не было нужно. Магазин, который уже принимает заказы на WordPress, не становится надёжнее оттого, что главная переезжает на более новый фреймворк. Продукт, который в основном API и доска, не становится яснее оттого, что я втиснул его в ту же тему, что и магазин. Я выбираю стек, который уже держит поведение, и держу границу достаточно резкой, чтобы один человек всё ещё видел на ту сторону.
Оставайтесь там, где бизнес уже живёт
Если выручка — оформление WooCommerce, работа лежит рядом с этим оформлением: тема, плагины, которым я правда доверяю, сервер, почта, копии. Перенос каталога в отдельный фронт, чтобы стек выглядел современно, — проект. Сам по себе он не чинит промокод и пропущенный webhook. У меня больше терпения на простую правку PHP, которая выйдет на этой неделе, чем на миграцию, чей выигрыш эстетический.
Laravel уместен, когда это приложение со своими правилами, своими очередями и своей админкой, и его не стоит гнуть в страницы. Контентный конвейер с потолком расходов и шагом человеческого согласия — такое приложение. Маркетинговый сайт — нет.
| Система уже и есть | Беру | Не беру |
|---|---|---|
| Магазин, который принимает заказы | WordPress, WooCommerce и сервер вокруг них | Переписывание, чтобы главная стала другим фреймворком |
| Приложение с очередями и админкой | Laravel, или Nest, если остальной продукт уже на TypeScript | Куча плагинов, которая притворяется продуктом |
| Типизированный интерфейс, общий для доски и API | TypeScript, от начала до конца | Второй язык только ради кнопок |
| Поиск, оценка, небольшой сервис поверх документов | Python | PHP-рантайм магазина, из лояльности |
Один язык внутри продукта, не на всю карьеру
Внутри одного продукта я хочу один основной язык, чтобы изменение API и изменение экрана были одним просмотром. По всей работе я не делаю вид, что всё — один язык. PHP, TypeScript и Python здесь в проде нарочно. Ошибка — мешать их в одном пути запроса, потому что каждый слой был чьим-то предпочтением.
PostgreSQL, когда у данных есть связи и я хочу, чтобы база их держала. MySQL, когда магазин уже на нём и перенос не задача. Redis для очереди или кэша, не как второй источник правды. Docker и скучный nginx, когда выкладку нужно описать, а не когда хочется учить оркестратор.
Переписывание должно назвать инцидент, который оно убирает
Я прошу одно предложение, прежде чем новый фреймворк попадёт в план. Какой инцидент, который текущий стек не может закрыть, уходит из-за переезда? Если предложение про вкус, найм или доклад на конференции, переезд ждёт. Если предложение такое: «плагин оформления не умеет выразить это правило цены, и я уже дважды обходил его заплаткой», это настоящее предложение, и я всё равно ищу заплатку меньше, прежде чем новую витрину. Меньшая заплатка обычно есть.
Тот же тест — для сервиса, который тянет добавить рядом с магазином. Очередь оправдана, когда запрос должен пережить повтор. Отдельный фронт оправдан, когда один и тот же API нужен двум клиентам, а не одному разработчику. Новая база почти никогда не оправдана в том же квартале, что и проблема надёжности. Данные, которые у вас уже есть, и есть система. Перенос — отдельный проект со своим инвентарём, и он не чинит промокод.
Я могу держать магазин и соседний сервис, потому что они встречаются на описанном крае: webhook, очередь, таблица. Я не могу держать систему, края которой — «спроси того, кто это собрал». Этим человеком должен быть я, и после запуска тоже. Новому инструменту приходится платить аренду. Если он не убирает передачу из рук в руки или класс инцидентов, это вкус, а вкус подождёт.
Выберите стек, который держит следующий инцидент в одной голове. Новизна должна победить это, а не наоборот.
