diciembre 6, 2024

Una introducción a CQRS en NestJS


Un enfoque común para desarrollar NestJS es crear servicios con los que los controladores se comuniquen para acceder a los datos. Pero este enfoque no es el único patrón de diseño válido en NestJS. Hay otros patrones de diseño, como el patrón de diseño CQRS.


CQRS es un patrón de diseño que separa las operaciones de lectura y escritura de una aplicación. Esta separación puede ayudar a mejorar la escalabilidad, el rendimiento y la capacidad de mantenimiento.

Aprenda todo sobre CQRS y cómo aplicarlo al crear una API de NestJS.


¿Qué es CQRS?

Extensión CQRS representa acción consulta segregación de responsabilidad. Implementar el uso de comandos crear, actualizar y eliminar datos e consultas para recuperar los datos. Esto elimina la necesidad de implementar llamadas a la base de datos de una aplicación en los servicios.

También permite una distinción clara entre la lógica de consultar la base de datos en busca de datos y realizar otras acciones en una aplicación.

El enfoque CQRS es útil en diseño dirigido por dominio, que le permite separar la lógica del dominio y las operaciones de infraestructura en su aplicación. También puede usarlo para implementar una lógica comercial compleja, pero no se recomienda para aplicaciones más simples.

Usando CQRS en una API de NestJS

Puede usar el patrón de diseño CQRS en una API integrada en NestJS. Debe tener Node.js instalado en su computadora y una versión reciente de NestJS para continuar.

Use los siguientes pasos para crear una aplicación de blog simple que implemente el patrón de diseño CQRS.

Crear un proyecto de Nest

Crea un nuevo proyecto de Nest y genera un archivo enviar recurso para una aplicación de blog. Puede hacer esto ejecutando los siguientes comandos en una terminal:

 nest new nestjs-cqrs
nest g module posts
nest g controller posts
nest g service posts

Instalar dependencias

Después de completar los pasos anteriores, ejecute este comando de terminal para instalar el paquete NestJS CQRS:

 npm install --save @nestjs/cqrs 

Crear un servicio postal

Agregue el siguiente código a su puestos.servicio.ts archivo para definir el servicio Postal clase.

 
import { Injectable } from '@nestjs/common';

export interface Post {
    title: string;
    content: string;
}

@Injectable()
export class PostService {
  private readonly posts: Post[] = [];

  create(post: Post): Post {
    this.posts.push(post);
    return post;
  }

  findById(id: number): Post {
    return this.posts.find(post => post.id === id);
  }
}

EL servicio Postal define crear Y encontrar por Id métodos para crear una nueva publicación y obtener una publicación existente por su id.

Definir comandos y consultas

El siguiente paso es definir las consultas y comandos fundamentales para el patrón de diseño CQRS.

En el correo directorio, cree dos nuevos archivos: crearPostCommand.command.ts Y getPostQuery.query.ts. El archivo de comando debería verse así:

 
export class CreatePostCommand {
  constructor(public readonly title: string, public readonly content: string) {}
}

Y el archivo de definición de consulta, así:

 
export class GetPostQuery {
  constructor(public readonly id: number) {}
}

Crear controladores de comandos y consultas

Una vez que haya definido con éxito sus comandos y consultas, debe crear sus controladores. Un controlador es una función que ejecuta un comando o consulta y devuelve el resultado.

Crear un gerentes.ts archivo en su enviar directorio y pegue el siguiente código en él:

 
import { CommandHandler, ICommandHandler } from '@nestjs/cqrs';
import { CreatePostCommand } from './createPostCommand.command.ts';
import { PostService } from './post.service';

@CommandHandler(CreatePostCommand)
export class CreatePostHandler implements ICommandHandler<CreatePostCommand> {
  constructor(private readonly postService: PostService) {}

  async execute(command: CreatePostCommand) {
    const { name, price } = command;
    const post = await this.postService.create(title, content);
    return post;
  }
}

En el mismo gerentes.ts archivo, puede modificar las declaraciones de importación para incluir las siguientes, para permitirle trabajar con consultas. A continuación, puede implementar el controlador de consultas como se muestra en el siguiente código:

 
import { QueryHandler, IQueryHandler } from '@nestjs/cqrs';
import { GetPostQuery } from './getPostQuery.query';
import { PostService } from './post.service';


@QueryHandler(GetProductQuery)
export class GetPostHandler implements IQueryHandler<GetPostQuery> {
  constructor(private readonly postService: PostService) {}

  async execute(query: GetPostQuery) {
    const { id } = query;
    const post = await this.postService.findOneById(id);
    return post;
  }
}

Administradores de registro

El último paso es registrar los controladores de comandos y consultas con el módulo NestJS.

 
import { Module } from '@nestjs/common';
import { CommandHandlers, QueryHandlers } from 'handlers.ts';
import { PostService } from './post.service';

@Module({
  providers: [
    PostService,
    ...CommandHandlers,
    ...QueryHandlers,
  ],
})
export class PostModule {}

Este código registra el servicio Postal, Manejador de comandosY controlador de consultas En el proveedores vector. Usando un operador de propagación () es unir arreglos de pedido gerentes y dominio gerentes en el proveedores vector.

Ejecutar comandos y consultas

Los comandos registrados y los controladores de consultas se pueden usar en los controladores. El siguiente código es la implementación de un correo controlador que aceptará solicitudes HTTP y devolverá las respuestas solicitadas.

 
import { Body, Controller, Post } from '@nestjs/common';
import { CommandBus } from '@nestjs/cqrs';
import { CreatePostCommand } from './createPostCommand.command.ts';


@Controller('posts')
export class PostController {
  constructor(private readonly commandBus: CommandBus) {}

  @Post()
  async createPost(@Body() body: { title: string; content: string }) {
    const { title, content } = body;
    const command = new CreatePostCommand(title, content);
    const post = await this.commandBus.execute(command);
    return post;
  }
}

En el código anterior, el autobús de mando realiza el CreatePostCommand y crear una nueva publicación.

Este código muestra cómo implementar un controlador que utiliza una consulta:

 
import { Controller, Get, Param } from '@nestjs/common';
import { QueryBus } from '@nestjs/cqrs';
import { GetPostQuery } from './getPostQuery.query';

@Controller('posts')
export class PostController {
  constructor(private readonly queryBus: QueryBus) {}

  @Get(':id')
  async getPost(@Param('id') id: number) {
    const query = new GetPostQuery(id);
    const post = await this.queryBus.execute(query);
    return post;
  }
}

EL consultaBus realiza GetPostQuery que obtiene la publicación con la identificación dada y la devuelve.

Después de completar todos los pasos anteriores, ahora debería tener una aplicación funcional y minimalista para crear y obtener publicaciones de blog.

Si bien el código aquí usa una matriz para almacenar publicaciones creadas en la memoria, es más probable que esté usando una base de datos en producción. Puede usar una base de datos SQL o una base de datos NoSQL como MongoDB, ya que NestJS admite ambas opciones.

Creación de API con el patrón de diseño CQRS

La incorporación del patrón de diseño CQRS en su aplicación NestJS puede ayudar con la escalabilidad, el rendimiento y la capacidad de mantenimiento. CQRS permite operaciones más eficientes y optimizadas al separar las operaciones de lectura y escritura realizadas por una aplicación.

El paquete @nestjs/cqrs proporciona un componente básico para implementar CQRS en NestJS con comandos y controladores de consultas. En general, CQRS es un modelo poderoso que puede ayudar a crear aplicaciones más eficientes y escalables, y debe sopesar sus opciones antes de usarlo.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *