Web-приложения

Архитектура веб-приложения: как выбрать основу продукта

Для большинства новых продуктов безопасная отправная точка — модульный монолит с явными границами, одной основной базой и наблюдаемыми интеграциями. Усложнять архитектуру стоит только под измеримый риск.

Редакция ХЭМСОбновлено 7 августа 202619 мин
Архитектура веб-приложения с интерфейсом, API, модулями и хранилищем данных

Коротко

Архитектуру веб-приложения выбирают по критичным сценариям, нагрузке, данным, интеграциям, требованиям к доступности и возможностям команды. Для MVP обычно достаточно модульного монолита: он дешевле в разработке и эксплуатации. Микросервисы оправданы, когда модули нужно независимо масштабировать, выпускать или изолировать, а команда готова обслуживать распределённую систему.

Карта архитектурного решения до выбора стека

До обсуждения языка и фреймворка команда фиксирует архитектурную карточку. В ней нет декоративной схемы: только ограничения, проверяемые решения и последствия. Такой документ защищает проект от двух крайностей — случайного набора технологий и преждевременных микросервисов.

ВопросРешение для первого релизаКогда пересматривать
Границы системыМодули пользователей, заказов, платежей и отчётовКогда модуль получает отдельную команду или цикл релизов
Источник истиныОдна основная БД; внешние статусы приходят через адаптерыПри появлении независимых контуров данных
ИнтеграцииAPI с таймаутами, повтором и журналом ошибокПри росте очереди или критичности обмена
ДоступПроверка прав на сервере для каждого объектаПри добавлении организаций, филиалов и партнёров
НаблюдаемостьЛоги, ошибки, метрики ответа и резервные копииПри появлении SLA и дежурной команды
  • Назовите три операции, потеря которых останавливает бизнес.
  • Зафиксируйте владельца и источник истины для каждого типа данных.
  • Опишите поведение системы при недоступности каждого внешнего API.
  • Проверьте права не только на экран, но и на конкретную запись.
  • Определите, как восстановить систему и сколько данных допустимо потерять.

Архитектура начинается не со стека, а с ограничений

Одно и то же приложение можно собрать разными способами. Правильный выбор зависит от критичных сценариев, количества пользователей, чувствительности данных, интеграций, доступности команды и темпа изменений. До обсуждения фреймворка нужно понять, что система обязана гарантировать.

Функциональные требования описывают действия: создать заказ, согласовать документ, назначить роль, провести платеж. Нефункциональные задают качество: время ответа, доступность, восстановление, аудит действий, срок хранения и географию данных.

Архитектура должна быть соразмерной риску. Для MVP опасна инфраструктура, которую маленькая команда не сможет обслуживать. Для финансово значимого кабинета опасен быстрый прототип без модели прав, журналирования и резервного восстановления.

  • Какие три пользовательских сценария критичны для бизнеса.
  • Какие данные нельзя потерять или показать не тому пользователю.
  • Какие внешние системы и протоколы обязательны.
  • Какой рост нагрузки реалистичен в ближайшие 12–18 месяцев.
  • Как часто нужно выпускать изменения и кто будет поддерживать продукт.
  • Какой простой допустим и сколько времени есть на восстановление.

Базовые слои архитектуры веб-приложения

Интерфейс отвечает за отображение состояния и пользовательские действия. API принимает запрос, проверяет контракт и передает управление бизнес-логике. Доменный слой реализует правила продукта. Доступ к данным сохраняет и извлекает состояние. Инфраструктура связывает очереди, файлы, внешние сервисы и мониторинг.

Разделение не означает отдельный сервер для каждого слоя. На старте они могут находиться в одном приложении и репозитории, но иметь четкие границы в коде. Тогда правила заказа не зависят напрямую от конкретной базы, а интерфейс не содержит расчетов, которые невозможно повторить через API.

Полезная граница проходит там, где меняется причина изменения. Политика скидки меняется из-за бизнеса, компонент кнопки — из-за интерфейса, драйвер платежной системы — из-за внешнего поставщика. Смешивание этих причин делает каждую доработку рискованнее.

СлойОтветственностьЧего в нем не должно быть
UIСостояние экрана и взаимодействиеСкрытых бизнес-правил и прямого SQL
APIКонтракт, валидация, авторизацияСлучайных форматов и логики интерфейса
ДоменПравила и процессы продуктаЗависимости от конкретного UI
ДанныеХранение, транзакции, запросыРешений о пользовательском опыте
ИнфраструктураОчереди, файлы, внешние сервисыНеконтролируемого влияния на домен

Модульный монолит или микросервисы

Монолит — не синоним хаоса. Модульный монолит хранит продукт в одном развертываемом приложении, но разделяет предметные области: пользователи, заказы, каталог, документы. Он проще в разработке, тестировании и транзакциях, поэтому часто подходит первой версии.

Микросервисы дают независимое развертывание и масштабирование частей системы, но добавляют сетевые отказы, распределенные данные, трассировку, версии контрактов и операционную нагрузку. Они оправданы, когда границы доменов устойчивы, разные части имеют разный профиль нагрузки или ими владеют автономные команды.

Переход можно подготовить без раннего дробления. Сначала выделяют модули и события внутри приложения, запрещают обход границ, документируют контракт. Если конкретный модуль действительно требует независимости, его проще вынести позже.

КритерийМодульный монолитМикросервисы
КомандаОдна или несколько тесно связанныхАвтономные команды с DevOps-компетенцией
ДанныеПростые общие транзакцииРазделенное владение и eventual consistency
РелизыОбщий, но управляемый pipelineНезависимые релизы сервисов
ЭксплуатацияНиже порог сложностиНужны оркестрация, трассировка и SRE-практики
Хороший стартБольшинство новых продуктовПодтвержденные организационные и нагрузочные причины
Микросервисы решают проблему независимости команд и доменов, а не автоматически делают приложение современным.

Данные, API и интеграции

Модель данных должна выражать бизнес, а не копировать поля экранов. У каждой сущности определяют владельца, жизненный цикл, обязательные инварианты и историю изменений. Например, заказ — не просто форма: у него есть состав, цена на момент покупки, статусы, платежи и последствия отмены.

API проектируют как контракт. Версия, форматы ошибок, идемпотентность, пагинация, авторизация и ограничения описываются до интеграции. Для длительных операций используют очередь и возвращают статус, а не удерживают соединение до завершения.

Вебхуки требуют подписи, повторной доставки и защиты от дублей. Платеж или внешний заказ нельзя создавать повторно только потому, что поставщик повторил уведомление. Подробный чек-лист есть в статье об API-интеграциях.

  1. Определить источник истиныКакая система владеет клиентом, заказом, оплатой и документом.
  2. Описать контрактСхема запроса, ответа, ошибки, права и ограничения.
  3. Учесть повторИдемпотентность команд и дедупликация событий.
  4. Разделить синхронное и фоновоеБыстрый ответ пользователю, очередь для тяжелой обработки.
  5. Добавить наблюдаемостьCorrelation ID, журнал интеграций, метрики и оповещения.

Безопасность как архитектурное свойство

Безопасность нельзя добавить в конце одним тестом. Модель ролей влияет на данные и API, управление секретами — на развертывание, аудит — на хранение, обновление зависимостей — на процесс разработки. Эти решения нужно принять до массового написания кода.

Минимальный принцип — наименьшие привилегии. Пользователь, сервис и сотрудник получают только необходимые действия и данные. Проверка выполняется на сервере для каждого защищенного ресурса; скрытая кнопка в интерфейсе не является контролем доступа.

Чувствительные данные классифицируют, шифруют при передаче и хранении там, где это оправдано, ограничивают экспорт и логирование. Резервная копия тоже содержит данные и требует контроля доступа, проверки восстановления и срока хранения.

  • Централизованная аутентификация и серверная авторизация.
  • Разделение ролей, организаций и областей данных.
  • Управление секретами вне репозитория и клиентского кода.
  • Валидация входа, защита сессии и лимиты запросов.
  • Аудит критичных действий без утечки чувствительных полей.
  • Регулярное обновление зависимостей и проверка уязвимостей.

Надежность, развертывание и наблюдаемость

Надежность начинается с определения допустимого отказа. Если отчет можно пересчитать завтра, ему не нужен тот же уровень доступности, что оплате. Для критичных сценариев задают SLO, время восстановления и допустимую потерю данных.

Приложение развертывают воспроизводимо: инфраструктура и конфигурация описаны, миграции обратимы или имеют план отката, среды разделены, секреты управляются отдельно. Контейнеризация помогает повторяемости, но сама по себе не обеспечивает устойчивость.

Наблюдаемость объединяет логи, метрики и трассировку. Команда должна быстро ответить: какой запрос сломался, в каком релизе, для какого клиента, на каком внешнем сервисе и сколько операций затронуто. Среднее время ответа без percentiles и бизнес-контекста скрывает реальные пики.

СигналНа какой вопрос отвечаетПример
МетрикаНасколько часто и масштабноОшибка оплаты, p95 API, длина очереди
ЛогЧто произошло в конкретной точкеСтатус обработчика без секретов
ТрассировкаГде задержался сквозной запросGateway → API → база → платежи
Бизнес-событиеКак затронут процессЗаказ не перешел в подтвержденный

Как принять архитектурное решение и не заморозить продукт

Ключевые решения фиксируют короткими ADR: контекст, варианты, выбранный подход, последствия и условия пересмотра. Это помогает новой команде понять не только что сделано, но и почему. Документ обновляют при изменении исходных ограничений.

Для первой версии выбирают минимальную архитектуру, которая безопасно выполняет критичный сценарий и оставляет путь развития. В статье о разработке ПО разобраны границы заказного решения, а этапы разработки показывают, когда проверять архитектуру.

Архитектурный review проводят до реализации рискованных интеграций и после появления реальных данных о нагрузке. Цель — не защитить первоначальную схему, а регулярно проверять, продолжает ли она помогать продукту.

  1. Сформулировать сценарии и рискиДанные, нагрузка, доступность, интеграции и команда.
  2. Выбрать простейший достаточный вариантБез преждевременной распределенности и скрытого долга.
  3. Зафиксировать границыМодули, владельцы данных, контракты и правила зависимостей.
  4. Проверить прототипомРискованная интеграция, нагрузка или миграция до полной реализации.
  5. Пересматривать по фактамМетрики эксплуатации, рост продукта и изменения команды.

FAQ

Частые вопросы

01Какая архитектура лучше для нового веб-приложения?

Для многих новых продуктов разумен модульный монолит: он проще в разработке и эксплуатации, но сохраняет границы доменов. Решение меняется, если есть подтвержденные требования к независимым командам или масштабированию.

02Нужно ли использовать микросервисы для высокой нагрузки?

Не всегда. Сначала измеряют узкое место и масштабируют приложение, кеш, базу или фоновые задачи. Микросервисы оправданы, когда раздельное масштабирование и владение компенсируют операционную сложность.

03Когда выбирать SQL, а когда NoSQL?

Выбор зависит от модели и операций. Транзакционные бизнес-данные часто хорошо подходят реляционной базе; специализированное хранилище добавляют для конкретной задачи, а не вместо моделирования.

04Что должно остаться после архитектурного этапа?

Диаграмма контекста и контейнеров, модель данных, ключевые API-контракты, модель безопасности, решения ADR, план развертывания и прототипы главных рисков.

Источники и документация

Материал подготовлен редакцией ХЭМС на основе проектной практики. Цены и технические условия актуальны на дату публикации и уточняются после разбора задачи.

Обсудить проект

Спроектируем основу web-продукта

Разберем сценарии, данные, интеграции и риски. Зафиксируем границу MVP и архитектуру, которую команда сможет развивать после первого релиза.

Обсудить Web app MVP

Дальше по теме