При совместном использовании Iron и Express важно сразу определить границы ответственности между двумя слоями. Express чаще используется как гибкий HTTP-сервер с богатой экосистемой middleware, тогда как Iron обычно выступает как более структурированный каркас для маршрутизации и организации бизнес-логики.
Ключевая идея архитектуры — разделение приложения на слои:
Такое разделение позволяет избежать смешивания логики обработки запросов и доменной логики, что критично для масштабируемых приложений.
Типичный проект с использованием Iron и Express строится вокруг предсказуемой и расширяемой структуры:
project-root/
│
├── src/
│ ├── app/ # точка интеграции Express и Iron
│ ├── config/ # конфигурации окружения
│ ├── routes/ # маршруты Iron
│ ├── controllers/ # контроллеры (HTTP слой)
│ ├── services/ # бизнес-логика
│ ├── repositories/ # работа с данными
│ ├── middlewares/ # middleware Express и Iron
│ ├── utils/ # вспомогательные функции
│ ├── models/ # модели данных
│ └── errors/ # обработка ошибок
│
├── public/ # статические файлы (Express)
├── tests/ # тесты
├── package.json
└── server.js # запуск приложения
В проектах, где Express используется как базовый HTTP-сервер, а Iron как слой маршрутизации, точка входа обычно выглядит как связующий модуль.
Основная задача этого слоя — инициализация Express и подключение Iron как маршрутизатора.
Примерная структура логики:
Ключевым моментом является то, что Express не должен знать о бизнес-логике — он только передаёт управление Iron.
Интеграция строится вокруг передачи управления маршрутизацией.
Express выступает как контейнер HTTP-уровня, а Iron — как слой обработки маршрутов:
Такая схема позволяет:
Маршруты в Iron структурируются по функциональному признаку, а не по техническому.
Пример логической группировки:
Каждая группа маршрутов находится в отдельном модуле:
routes/
├── auth.routes.js
├── user.routes.js
├── product.routes.js
Внутри каждого файла описываются маршруты и привязка к контроллерам:
Важно, что Iron обычно позволяет более декларативную организацию маршрутов, что упрощает поддержку.
Контроллеры не должны содержать бизнес-логику. Их задача:
Типовая структура контроллера:
Контроллер становится адаптером между HTTP и доменной логикой.
Сервисы представляют собой ядро бизнес-логики приложения.
Их особенности:
Примеры задач сервиса:
Сервисы позволяют тестировать бизнес-логику отдельно от инфраструктуры.
Репозитории отделяют работу с базой данных от бизнес-логики.
Функции слоя:
Сервисы никогда не должны напрямую обращаться к базе данных — только через repository слой.
Middleware в таком проекте делится на два типа:
Важно избегать дублирования логики между слоями.
Централизованная обработка ошибок является обязательной частью архитектуры.
Стандартный подход:
Структура ошибок обычно включает:
Конфигурация должна быть отделена от логики приложения.
Обычно выделяются:
Файлы конфигурации не должны содержать бизнес-логики или вызовов Express/Iron.
В правильно организованной структуре зависимости направлены строго вниз:
Express → Iron → Controllers → Services → Repositories → DB
Нарушение этого направления приводит к:
При запросе GET /users/10:
/users/:idПроект часто делится на две зоны:
Такое разделение позволяет:
По мере роста проекта структура может расширяться:
Важно сохранять правило: каждый слой не должен знать о реализации слоя ниже, только о его интерфейсе.