Ответ
В Nest.js, помимо поддержки микросервисов, активно используются и другие архитектурные паттерны.
1. Модульная архитектура. Приложение организуется в виде независимых модулей с помощью декоратора @Module(). Каждый модуль инкапсулирует контроллеры, провайдеры и импорты.
@Module({
imports: [DatabaseModule],
controllers: [UsersController],
providers: [UsersService],
})
export class UsersModule {}
2. Слоистая архитектура (Controllers → Services → Repositories). Это стандартный подход для разделения ответственности.
@Controller('users') // Слой представления/API
export class UsersController {
constructor(private usersService: UsersService) {}
}
@Injectable() // Слой бизнес-логики
export class UsersService {
constructor(private usersRepository: UsersRepository) {}
}
@Injectable() // Слой доступа к данным
export class UsersRepository {}
3. Поддержка CQRS (Command Query Responsibility Segregation). Доступна через пакет @nestjs/cqrs для разделения операций записи (команды) и чтения (запросы).
// Command Handler
@CommandHandler(CreateUserCommand)
export class CreateUserHandler implements ICommandHandler<CreateUserCommand> {
async execute(command: CreateUserCommand) {
// Логика создания пользователя
}
}
4. Event-Driven Architecture. Можно использовать встроенный EventEmitter или интегрировать брокеры сообщений (Kafka, RabbitMQ) для асинхронной коммуникации через события.
5. Принципы Domain-Driven Design (DDD). Nest.js не навязывает DDD, но его модульная система и внедрение зависимостей хорошо подходят для организации доменных моделей, агрегатов и доменных сервисов.
Ответ 18+ 🔞
Смотри, тут про Nest.js, аж овердохуища архитектурных паттернов намешано. Ну, типа, кроме микросервисов, там ещё куча всего есть, чтобы мозг не взорвался от спагетти-кода.
1. Модульная архитектура. Это когда ты не сваливаешь всё в одну кучу, а раскладываешь по полочкам, как нормальный человек. Каждый модуль — это такой отдельный ящичек, где лежат свои контроллеры, сервисы и прочая хрень. Делается это через @Module(). Выглядит прилично, не то что какой-нибудь бардак.
@Module({
imports: [DatabaseModule],
controllers: [UsersController],
providers: [UsersService],
})
export class UsersModule {}
2. Слоистая архитектура (Controllers → Services → Repositories). Классика жанра, ёпта. Разделил ответственность — и спи спокойно. Контроллеры ручки апишки ловят, сервисы мозги думают, а репозитории в базу лазают. Всё чинно, благородно, никакой ерунды.
@Controller('users') // Этот чувак с клиентом общается
export class UsersController {
constructor(private usersService: UsersService) {}
}
@Injectable() // А этот — бизнес-логику пасёт
export class UsersService {
constructor(private usersRepository: UsersRepository) {}
}
@Injectable() // Этот — в базу данных тырится, как крот
export class UsersRepository {}
3. Поддержка CQRS (Command Query Responsibility Segregation). Вот это уже для ценителей, когда чтение и запись — это два разных мира. Взял пакет @nestjs/cqrs и поехал. Для команд — одни обработчики, для запросов — другие. Сложновато сначала, зато потом масштабируется на ура.
// Command Handler
@CommandHandler(CreateUserCommand)
export class CreateUserHandler implements ICommandHandler<CreateUserCommand> {
async execute(command: CreateUserCommand) {
// Тут магия создания юзера происходит
}
}
4. Event-Driven Architecture. Архитектура на событиях, когда всё шипит и потрескивает. Можно родной EventEmitter юзать, а можно и на серьёзные штуки вроде Kafka или RabbitMQ перейти. Отправил событие — и пошло-поехало, другие части приложения сами разберутся, что делать. Удобно, бля, для асинхронщины.
5. Принципы Domain-Driven Design (DDD). Сам Nest.js тебе DDD в зубы не суёт, но если ты сам не лох, то можешь на его модулях и DI такую доменную модель выстроить, что мама не горюй. Агрегаты, сущности, доменные сервисы — всё это можно красиво упаковать. Главное — мозги включить и не делать из этого мартышлюшку.
В общем, инструментов — вагон и маленькая тележка. Выбирай, что под задачу подходит, и не выёбывайся со сложными паттернами там, где можно просто и надёжно.