Перейти к содержанию
  • Категории
  • Последние
  • Метки
  • Популярные
  • Пользователи
  • Группы
Свернуть
Логотип бренда
Категории
  1. Главная
  2. Категории
  3. Бекенд, разработка серверов
  4. NestJs
  5. Модули в Nest JS - 1.2

Модули в Nest JS - 1.2

Запланировано Прикреплена Закрыта Перенесена NestJs
2 Сообщения 2 Постеры 140 Просмотры 1 Watching
  • Сначала старые
  • Сначала новые
  • По количеству голосов
Ответить
  • Ответить, создав новую тему
Авторизуйтесь, чтобы ответить
Эта тема была удалена. Только пользователи с правом управления темами могут её видеть.
  • kirilljsK Не в сети
    kirilljsK Не в сети
    kirilljs
    js
    написал в отредактировано
    #1

    Модуль — это важная часть приложения на Nest. Каждое приложение начинается с корневого модуля, который Nest использует для создания структуры приложения. Эта структура помогает управлять зависимостями между модулями и провайдерами.

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

    Важно помнить, что модули в Nest не обязательно должны быть отдельными файлами. Это всего лишь абстракция, которая помогает структурировать приложение. Некоторые модули могут быть большими, другие — маленькими. Используя паттерн «композиция», разработчики могут создавать сложные модули из простых.

    Хотя Nest позволяет создать приложение с одним модулем, это подходит только для очень простых проектов. С увеличением сложности приложения становится очевидным, что использование нескольких модулей — более эффективный подход.

    modules.jpg

    Примечание: Абстракция «Модуль» в Nest реализует одноимённый структурный паттерн проектирования. Модуль объединяет данные, функции и физические компоненты в одну сущность, а взаимодействовать с ней можно через публичный интерфейс.

    Как работать с модулями в Nest

    В Nest модуль — это класс, помеченный декоратором @Module. Этот декоратор содержит метаданные, которые Nest использует для организации приложения.

    Декоратор @Module принимает объект, который описывает структуру модуля. В этом объекте можно указать провайдеры и контроллеры модуля, а также модули, от которых он зависит, и провайдеры, которые он экспортирует. Вот основные свойства:

    Свойство объекта Описание
    providers Список провайдеров модуля.
    controllers Список контроллеров модуля.
    imports Список импортируемых модулей.
    exports Список экспортируемых провайдеров модуля.

    Особое внимание стоит уделить свойствам imports и exports.

    • imports: здесь указываются модули, которые нужны текущему модулю. Если модуль использует функциональность других модулей, их нужно перечислить в этом свойстве. Импортированные модули могут использовать экспортируемые провайдеры.

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

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

    Модули на практике

    Чтобы понять, как работают модули в Nest, рассмотрим пример простого приложения — API для управления пользователями. В этом приложении нам понадобятся функции для запуска сервера и управления пользователями.

    Для REST API создадим контроллер UserController, который будет обрабатывать маршруты. Если у нас есть бизнес-логика и взаимодействие с базой данных, нам понадобится модуль UserService, который будет реализовывать эту логику. Также потребуется описание сущности «Пользователь», например, UserEntity.

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

    modules-1.jpg

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

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

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

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

    Примечание: Nest CLI позволяет быстро создать модуль с помощью команды: nest g module users.

    Пример организации кода для нашего модуля может выглядеть так:

    import { Module } from '@nestjs/common';
    import { UserController } from './user.controller';
    import { UserService } from './user.service';
    
    @Module({
      controllers: [UserController],
      providers: [UserService],
    })
    export class UserModule {}
    

    Новый модуль описывается как класс, например, UserModule, и помечается декоратором @Module. В этот декоратор передаётся объект с настройками модуля, где мы регистрируем контроллеры и провайдеры.

    Наш модуль пока ничего не экспортирует, но при необходимости можно добавить сервисы для использования в других модулях. Для этого в объект настроек нужно добавить свойство exports. Мы рассмотрим это на практике позже.

    Примечание: Хороший модуль должен решать одну конкретную задачу. Не стоит объединять всю функциональность приложения в одном модуле. Лучше разбивать на несколько, минимизируя зависимости между модулями.

    modules-2.jpg

    Для каждого модуля обычно создаётся отдельная директория, где размещаются все его компоненты: сервисы, контроллеры и вспомогательные скрипты. Это позволяет удобно организовать код и иметь всё, что связано с модулем, в одном месте.

    Подключение модуля

    Чтобы использовать функциональность модуля, его нужно подключить в другом модуле. Как уже упоминалось, любое приложение на Nest состоит как минимум из одного модуля, который называется корневым (обычно AppModule). Чтобы активировать функциональность UserModule, его необходимо подключить к корневому модулю приложения.

    // Файл app.module.ts
    
    import { Module } from '@nestjs/common';
    import { UserModule } from './cats/user.module';
    
    @Module({
      imports: [UserModule],
    })
    export class AppModule {}
    

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

    Переиспользование модулей

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

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

    Например, если нужно разделить экземпляр UserService между модулями, просто экспортируйте этот провайдер из UserModule. Для этого добавьте соответствующий ключ в объект настроек модуля:

    import { Module } from '@nestjs/common';
    import { UserController } from './user.controller';
    import { UserService } from './user.service';
    
    @Module({
      controllers: [UserController],
      providers: [UserService],
      
      // Добавляем экспорт провайдера
      exports: [UserService]
    })
    export class UserModule {}
    

    Теперь любой модуль, который импортирует UserModule, получает доступ к UserService, используя один и тот же экземпляр.

    Реэкспорт модулей

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

    @Module({
      imports: [FooModule],
      exports: [FooModule]
    })
    export class UserModule {}
    

    Принцип остаётся прежним: в exports можно перечислять как провайдеры, так и модули для реэкспорта. В приведённом примере UserModule импортирует FooModule и реэкспортирует его, делая доступным для других модулей, которые импортируют UserModule.

    Внедрение зависимостей

    В класс модуля можно внедрять провайдеров как зависимости через конструктор. Это может быть полезно при настройке модуля. Рассмотрим это на примере:

    import { Module } from '@nestjs/common';
    import { UserController } from './user.controller';
    import { UserService } from './user.service';
    
    @Module({
      controllers: [UserController],
      providers: [UserService],
    })
    export class UserModule {
      // UserService внедряется с помощью DI
      constructor(private userService: UserService) {}
    }
    

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

    Глобальные модули

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

    Чтобы сделать модуль глобальным, нужно аннотировать его декоратором @Global. Глобальные модули регистрируются только один раз, обычно в корневом модуле приложения.

    Рассмотрим пример с модулем UserModule. Аннотируем его декоратором @Global, и теперь провайдер UserService станет доступен другим модулям для внедрения без необходимости импортировать UserModule.

    import { Module, Global } from '@nestjs/common';
    import { UserController } from './user.controller';
    import { UserService } from './user.service';
    
    // Сделаем модуль глобальным
    @Global()
    @Module({
      controllers: [UserController],
      providers: [UserService],
    
      // Экспортируемые провайдеры
      // доступны другим модулям для внедрения
      // в качестве зависимости без необходимости
      // импортировать UserModule.
      exports: [UserService],
    })
    export class UserModule {}
    

    Хотя создание глобальных модулей удобно, использовать эту возможность нужно осторожно. Не стоит делать все модули глобальными, так как это может привести к сильной связанности между ними. Когда приложение вырастет, будет трудно отслеживать связи между модулями, и рефакторинг станет сложным. Используйте глобальные модули с осторожностью.

    Заключение

    Модуль — это ключевая абстракция в Nest. Его можно сравнить с компонентом, отвечающим за определённую функциональность приложения. Мы рассмотрели, как объявлять модули, использовать декоратор @Module, выполнять реэкспорт модулей и другие аспекты.

    Любое Nest-приложение состоит минимум из одного модуля, но не стоит складывать всю функциональность в один модуль. Разделение на модули упрощает поддержку и выделяет функциональность в отдельные компоненты.

    1 ответ Последний ответ
    2
    • MugiwaraM Не в сети
      MugiwaraM Не в сети
      Mugiwara
      написал в отредактировано
      #2

      Круто! Давай про Гварды еще

      1 ответ Последний ответ
      0

      • Войти

      • Нет учётной записи? Зарегистрироваться

      • Войдите или зарегистрируйтесь для поиска.
      • Первое сообщение
        Последнее сообщение
      0
      • Категории
      • Последние
      • Метки
      • Популярные
      • Пользователи
      • Группы