Une approche courante du développement NestJS consiste à construire des services avec lesquels les contrôleurs communiquent pour accéder aux données. Mais cette approche n’est pas le seul modèle de conception valable dans NestJS. Il existe d’autres modèles de conception, comme le modèle de conception CQRS.


CQRS est un modèle de conception qui sépare les opérations de lecture et d’écriture d’une application. Cette séparation peut contribuer à améliorer l’évolutivité, les performances et la maintenabilité.

Découvrez tout sur le CQRS et comment vous pouvez l’appliquer lors de la construction d’une API NestJS.


Qu’est-ce que le CQRS ?

CQRS signifie séparation des responsabilités commande-requête. Il met en œuvre l’utilisation de commandes pour créer, mettre à jour et supprimer des données et des requêtes pour récupérer des données. Cela permet d’éliminer la nécessité d’implémenter les appels à la base de données d’une application dans des services.

Cela permet également d’établir une distinction claire entre la logique d’interrogation de la base de données et l’exécution d’autres actions dans une application.

L’approche CQRS est utile pour la conception pilotée par le domainequi vous permet de séparer la logique du domaine et les opérations d’infrastructure dans votre application. Vous pouvez également l’utiliser pour mettre en œuvre une logique métier complexe, mais cela n’est pas recommandé pour les applications plus simples.

Utiliser CQRS dans une API NestJS

Vous pouvez utiliser le design pattern CQRS dans une API que vous construisez avec NestJS. Pour suivre le cours, vous devez avoir Node.js installé sur votre ordinateur et une version récente de NestJS.

Suivez les étapes suivantes pour créer une application de blog simple qui met en œuvre le modèle de conception CQRS.

Créer un projet Nest

Créer un nouveau projet Nest et générer un post pour une application de blog. Vous pouvez le faire en exécutant les commandes suivantes dans un terminal :

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

Installer les dépendances

Après avoir effectué les étapes ci-dessus, exécutez cette commande de terminal pour installer le paquet NestJS CQRS :

 npm install --save @nestjs/cqrs 

Créer un Post Service

Ajoutez le code suivant à votre posts.service.ts pour définir le fichier PostService classe.

 // posts.service.ts
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);
  }
}

Le PostService définit créer et findById méthodes permettant de créer un nouveau message et d’obtenir un message existant à partir de son identifiant.

Définir les commandes et les requêtes

L’étape suivante consiste à définir les requêtes et les commandes qui sont au cœur du modèle de conception du CQRS.

Dans le postes créer deux nouveaux fichiers : créerPostCommand.command.ts et getPostQuery.query.ts. Le fichier de commande devrait ressembler à ceci :

 // createPostCommand.command.ts
export class CreatePostCommand {
  constructor(public readonly title: string, public readonly content: string) {}
}

Et le fichier de définition de la requête, comme ceci :

 // getPostQuery.query.ts
export class GetPostQuery {
  constructor(public readonly id: number) {}
}

Créer des gestionnaires de commandes et de requêtes

Après avoir défini avec succès vos commandes et vos requêtes, vous devez créer des gestionnaires pour celles-ci. Un gestionnaire est une fonction qui exécute une commande ou une requête et renvoie le résultat.

Créer un handlers.ts dans votre fichier poste et y coller le code suivant :

 // handlers.ts
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;
  }
}

Dans le même répertoire handlers.ts vous pouvez modifier les déclarations d’importation pour inclure celles qui suivent, afin de pouvoir travailler avec des requêtes. Vous pouvez ensuite implémenter le gestionnaire de requêtes comme indiqué dans le code ci-dessous :

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

// query handler
@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;
  }
}

Enregistrer les gestionnaires

La dernière étape consiste à enregistrer les gestionnaires de commandes et de requêtes avec le module NestJS.

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

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

Ce code enregistre le module PostService, CommandHandlerset QueryHandlers dans la section fournisseurs array. L’utilisation d’un opérateur de diffusion () consiste à fusionner les tableaux de requête les manipulateurs et les commande dans l’outil de gestion des fournisseurs tableau.

Exécuter des commandes et des requêtes

Les commandes et les gestionnaires de requêtes enregistrés sont utilisables dans les contrôleurs. Le code suivant est l’implémentation d’un contrôleur postes contrôleur qui acceptera les requêtes HTTP et renverra les réponses requises.

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

// controller that implements command
@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;
  }
}

Dans le code ci-dessus, l’élément CommandBus exécute la commande CreatePostCommand et crée un nouveau message.

Ce code montre comment implémenter un contrôleur qui utilise une requête :

 // posts.controller.ts
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;
  }
}

Le contrôleur queryBus exécute GetPostQuery qui récupère le message avec l’identifiant donné et le renvoie.

Après avoir effectué toutes les étapes ci-dessus, vous devriez maintenant avoir une application minimaliste et fonctionnelle pour créer et récupérer des articles de blog.

Bien que le code ici utilise un tableau pour stocker les articles créés en mémoire, il est plus probable que vous utilisiez une base de données en production. Vous pouvez utiliser une base de données SQL ou une base de données NoSQL comme MongoDB, NestJS supportant les deux options.

Construire des API avec le modèle de conception CQRS

L’intégration du modèle de conception CQRS dans votre application NestJS peut contribuer à l’évolutivité, aux performances et à la maintenabilité. Le CQRS permet des opérations plus efficaces et optimisées en séparant les opérations de lecture et d’écriture effectuées par une application.

Le paquet @nestjs/cqrs fournit un bloc de construction pour l’implémentation du CQRS dans NestJS avec des commandes et des gestionnaires de requêtes. Dans l’ensemble, le CQRS est un modèle puissant qui peut aider à créer des applications plus efficaces et plus évolutives, et vous devriez évaluer vos options avant de l’utiliser.