Skip to content

Предлагаемая архитектура проекта

Библиотека Steroids Nest предполагает создание приложений с модульной архитектурой, при этом внутри каждого модуля используется луковичная архитектура.

Основные понятия

Модульная архитектура — это подход к разработке программного обеспечения, в котором приложение разбивается на независимые компоненты — модули. Каждый модуль выполняет определенную функцию и имеет свою логику и интерфейс для взаимодействия с другими модулями. Проект состоит из модулей, каждый из которых отвечает за определённую предметную область (авторизация, работа с файлами, управление пользователями и т.д.). Также стоит отметить, что эти модули соответствуют модулям NestJS.

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

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

Каждый модуль делится на две основные части: доменную логику (папки domain и usecases) и инфраструктурный код (папка infrastructure).

Эти два слоя (доменный и инфраструктурный) и один подслой (юзкейсы) имеют следующее направление зависимостей:

Инфраструктурный слой -> (Юзкейсы -> Доменный слой)

Такая архитектура обеспечивает:

  • Гибкость и масштабируемость
  • Независимость бизнес-логики от инструментов реализации
  • Упрощение поддерживания
  • Легкость тестирования
  • Читаемость и структурированность кода

Доменная часть

В доменной части находится основная бизнес-логика приложения: модели, сервисы, интерфейсы и валидаторы.

Кроме того, к этой части относятся юзкейсы (usecases) — классы, отвечающие за отдельные сценарии взаимодействия с системой.

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

Файловая структура

Файловая структура доменной части обычно содержит следующие директории:

  • constants - константы текущего модуля предметной области
  • dto - классы DTO (data transfer object)
  • enums - классы словарей, относящиеся к текущему модулю
  • helpers - классы или чистые функции, реализующие переиспользуемый в других участках кода функционал
  • interfaces - интерфейсы зависимостей (как правило, инфраструктурных), которые используются бизнес-логикой для взаимодействия с классами, реализующими данные интерфейсы
  • models - модели предметной области. Представляют собой классы с набором полей, объявленных с помощью Fields декораторов
  • services - классы, реализующие определенную бизнес-логику, экземпляры которых находятся в DI контейнере приложения. В данной директории, как правило, находятся CRUD-сервисы, реализующие базовые операции взаимодействия с моделью и наследованные от базового сервиса CrudService.
  • validators - классы или функции, отвечающие за валидацию (см Валидация)
  • usecases - классы юзкейсов

Юзкейсы (UseCases)

Юзкейс - класс, реализующий отдельный сценарий взаимодействия с системой (например, создать/отменить заказ, сменить пароль, отправить сообщение и т.д.). Данный класс, как правило, содержит один публичный метод вызова.

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

Инфраструктурная часть

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

Файловая структура

Файловая структура инфраструктурной части обычно содержит следующие директории:

  • controllers - HTTP-контроллеры приложения
  • decorators - декораторы
  • guards - гарды, относящиеся к данному модулю
  • migrations - классы миграций
  • repositories - репозитории приложения. Как правило, это CRUD-репозитории реализующие базовые операции взаимодействия с моделью из домена и наследованные от базового сервиса CrudRepository.
  • services - классы, реализующие инфраструктурную логику приложения (обращения к внешним источникам, использование внешних зависимостей и т.д.)
  • subscribers - слушатели событий, генерируемых с помощью EventEmitter
  • tables - классы сущностей, необходимые для работы ORM. Как правило, здесь находятся Entity классы для TypeORM