Nouveau : Datasets open source gratuits disponibles !Decouvrir →
🟢
Avance 30 min NestJS

Microservices avec NestJS

Pourquoi Microservices avec NestJS ?

Dans un monde où les applications croissent rapidement en taille et en complexité, il est devenu nécessaire d'organiser le code en services plus petits et plus indépendants. Les microservices offrent cette possibilité, permettant à une application de se développer et évoluer de manière modulaire et échelonnable.

Un cas concret : imaginez une application e-commerce qui nécessite des services distincts pour la gestion des commandes, les paiements, le stockage des produits et l'authentification des utilisateurs. Chaque service peut être développé, testé et déployé indépendamment, ce qui accélère le développement global.

Prerequis

  • Connaissances nécessaires :

    • Langage TypeScript
    • Framework NestJS
    • Concept de microservices
    • Connaissance des bases de données (SQL/NoSQL)
    • Compréhension des API RESTful
    • Familiarité avec les outils de versionnement (Git)
  • Outils à installer :

    • Node.js v14.x ou ultérieur
    • npm v6.x ou ultérieur
    • NestJS CLI

Concepts fondamentaux

Concept 1: Création d'un Microservice avec NestJS

La première étape pour créer un microservice est de générer un nouveau projet NestJS en utilisant le CLI.

nest new my-microservice

Cela crée une structure de base du projet, incluant des fichiers comme app.module.ts, main.ts et d'autres fichiers dépendants.

Concept 2: Communication entre Microservices

Les microservices communiquent généralement via des canaux de messagerie, tels que RabbitMQ ou Kafka. NestJS offre un module pour faciliter cette communication.

npm install --save @nestjs/microservices

Ajoutez le module au fichier app.module.ts :

import { Module } from '@nestjs/common';
import { ClientsModule, Transport } from '@nestjs/microservices';

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'PRODUCT_SERVICE',
        transport: Transport.RMQ,
        options: {
          urls: ['amqp://localhost:5672'],
          queue: 'products_queue',
          queueOptions: { durable: false },
        },
      },
    ]),
  ],
})
export class AppModule {}

Concept 3: Définition d'Interfaces et DTO

Les Data Transfer Objects (DTO) sont utilisés pour définir les structures des données en entrée et sortie.

// product.dto.ts
export class CreateProductDto {
  name: string;
  price: number;
}

export class UpdateProductDto {
  name?: string;
  price?: number;
}

Concept 4: Définition de Services et Controllers

Les services contiennent la logique métier, tandis que les contrôleurs gèrent les requêtes HTTP.

// product.service.ts
import { Injectable } from '@nestjs/common';
import { CreateProductDto, UpdateProductDto } from './product.dto';

@Injectable()
export class ProductService {
  private products = [];

  create(createProductDto: CreateProductDto) {
    this.products.push({ ...createProductDto, id: Math.random().toString(36).substring(2, 9) });
    return this.products;
  }

  update(id: string, updateProductDto: UpdateProductDto) {
    const productIndex = this.products.findIndex(p => p.id === id);
    if (productIndex !== -1) {
      this.products[productIndex] = { ...this.products[productIndex], ...updateProductDto };
    }
    return this.products;
  }

  findAll() {
    return this.products;
  }

  findOne(id: string) {
    return this.products.find(p => p.id === id);
  }
}
typescript
// product.controller.ts
import { Controller, Post, Get, Put, Delete, Param, Body } from '@nestjs/common';
import { ProductService } from './product.service';
import { CreateProductDto, UpdateProductDto } from './product.dto';

@Controller('products')
export class ProductController {
  constructor(private readonly productService: ProductService) {}

  @Post()
  create(@Body() createProductDto: CreateProductDto) {
    return this.productService.create(createProductDto);
  }

  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.productService.findOne(id);
  }

  @Put(':id')
  update(@Param('id') id: string, @Body() updateProductDto: UpdateProductDto) {
    return this.productService.update(id, updateProductDto);
  }

  @Get()
  findAll() {
    return this.productService.findAll();
  }
}

Mise en pratique : Projet fil rouge

Étape 1 : Création du Projet

Créez un nouveau projet NestJS :

nest new product-service
cd product-service

Étape 2 : Configuration de la Communication avec RabbitMQ

Ajoutez le module ClientsModule pour configurer RabbitMQ.

// app.module.ts
import { Module } from '@nestjs/common';
import { ClientsModule, Transport } from '@nestjs/microservices';

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'PRODUCT_SERVICE',
        transport: Transport.RMQ,
        options: {
          urls: ['amqp://localhost:5672'],
          queue: 'products_queue',
          queueOptions: { durable: false },
        },
      },
    ]),
  ],
})
export class AppModule {}

Étape 3 : Création des DTO

Créez les fichiers product.dto.ts :

// product.dto.ts
export class CreateProductDto {
  name: string;
  price: number;
}

export class UpdateProductDto {
  name?: string;
  price?: number;
}

Étape 4 : Création des Services et Controllers

Créez les fichiers product.service.ts et product.controller.ts :

// product.service.ts
import { Injectable } from '@nestjs/common';
import { CreateProductDto, UpdateProductDto } from './product.dto';

@Injectable()
export class ProductService {
  private products = [];

  create(createProductDto: CreateProductDto) {
    this.products.push({ ...createProductDto, id: Math.random().toString(36).substring(2, 9) });
    return this.products;
  }

  update(id: string, updateProductDto: UpdateProductDto) {
    const productIndex = this.products.findIndex(p => p.id === id);
    if (productIndex !== -1) {
      this.products[productIndex] = { ...this.products[productIndex], ...updateProductDto };
    }
    return this.products;
  }

  findAll() {
    return this.products;
  }

  findOne(id: string) {
    return this.products.find(p => p.id === id);
  }
}
typescript
// product.controller.ts
import { Controller, Post, Get, Put, Delete, Param, Body } from '@nestjs/common';
import { ProductService } from './product.service';
import { CreateProductDto, UpdateProductDto } from './product.dto';

@Controller('products')
export class ProductController {
  constructor(private readonly productService: ProductService) {}

  @Post()
  create(@Body() createProductDto: CreateProductDto) {
    return this.productService.create(createProductDto);
  }

  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.productService.findOne(id);
  }

  @Put(':id')
  update(@Param('id') id: string, @Body() updateProductDto: UpdateProductDto) {
    return this.productService.update(id, updateProductDto);
  }

  @Get()
  findAll() {
    return this.productService.findAll();
  }
}

Étape 5 : Configuration du Service

Ajoutez le service product.service.ts au fichier app.module.ts :

// app.module.ts
import { Module } from '@nestjs/common';
import { ClientsModule, Transport } from '@nestjs/microservices';
import { ProductController } from './product.controller';
import { ProductService } from './product.service';

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'PRODUCT_SERVICE',
        transport: Transport.RMQ,
        options: {
          urls: ['amqp://localhost:5672'],
          queue: 'products_queue',
          queueOptions: { durable: false },
        },
      },
    ]),
  ],
  controllers: [ProductController],
  providers: [ProductService],
})
export class AppModule {}

Étape 6 : Exécution du Service

Exécutez le service :

npm run start

Erreurs frequentes et debugging

Erreur 1 : TypeError: Cannot read property 'id' of undefined

Cela peut se produire si vous essayez d'accéder à une propriété sur un objet qui est undefined.

// ❌ Mauvais
const product = req.body;
const productId = product.id;

// ✅ Correct
const product = req.body;
if (product && product.id) {
  const productId = product.id;
}

Erreur 2 : Module not found: Can't resolve '@nestjs/microservices'

Assurez-vous d'avoir installé le module correctement.

npm install --save @nestjs/microservices

Erreur 3 : RabbitMQ connection failed

Vérifiez que RabbitMQ est en cours d'exécution et que les URL sont correctes.

Pour aller plus loin

  • Apprendre à utiliser des bases de données NoSQL avec NestJS
  • Intégrer des services externes (ex: Stripe pour les paiements)
  • Utiliser le pattern CQRS (Command Query Responsibility Segregation)

Défi pratique

Créez un microservice pour gérer les utilisateurs. Implémentez les fonctionnalités CRUD et configurez la communication avec RabbitMQ.

Besoin d'aide sur NestJS ?

Besoin d'aide sur un projet technique ? Decrivez-le pour des conseils personnalises.

Recevoir des conseils

Questions frequentes

Quels sont les avantages des microservices avec NestJS?
Les microservices avec NestJS offrent plusieurs avantages tels que la scalabilité, la facilité de maintenance et l'isolation entre les services. Ils permettent également une meilleure évolutivité et un développement plus rapide grâce à leur architecture modulaire.
Comment créer un nouveau microservice avec NestJS?
Pour créer un nouveau microservice avec NestJS, vous pouvez utiliser la commande `nest generate microservice `. Une fois le projet créé, vous pouvez y ajouter vos contrôleurs et services comme pour les applications NestJS standard.
Quelle est la différence entre une API REST et un microservice?
Une API REST (Representational State Transfer) expose des données sous forme de ressources via des méthodes HTTP. Un microservice, en revanche, est une application plus grande divisée en composants indépendants qui communiquent via des protocoles comme HTTP ou gRPC.

Pages liees

Chaque semaine, le meilleur de la tech francaise

Tendances, salaires, outils et opportunites — directement dans votre boite mail.

Gratuit. Desabonnement en un clic. Pas de spam.