web-dev-qa-db-fra.com

Comment diviser les microservices Nest.js en projets séparés?

Disons que je veux créer une plateforme de gestion de cinéma simpliste. Il nécessite peu de microservices: movies, cinemas, payments, etc.

Comment vous y prendriez-vous dans Nest.js? Je ne veux pas qu'ils soient dans le même grand dossier que cela ressemble à faire un monolithe. Je veux qu'ils soient des projets Nest.js distincts avec leurs propres référentiels git afin que je puisse les orchestrer avec Kubernetes plus tard.

Comment? Comment se connecter du service cinemas au service movies s'il s'agit de deux projets distincts et ne partagent que, disons, Redis?

Edit: Ce n'est pas une question sur les microservices en général. Il s'agit d'une question spécifique à Nest.js. J'ai lu la documentation, je sais qu'il y a des décorateurs comme @Client pour la connexion à la couche transport. Je veux juste savoir où utiliser ce décorateur et peut-être voir un court extrait de code sur "avoir deux référentiels Nest.js distincts comment les connecter ensemble afin qu'ils puissent se parler".

Je me fiche de la couche transport, cette chose que je peux comprendre moi-même. J'ai juste besoin de quelques conseils sur le cadre lui-même car je pense que la documentation fait défaut.

13
Tomasz Gałkowski

Je l'ai fait fonctionner. Fondamentalement, la façon de le faire est de créer deux projets distincts. Disons - l'un est un createMicroservice et un autre est juste une application HTTP (mais pourrait facilement être un autre microservice). J'ai utilisé une application "normale" pour pouvoir l'appeler facilement pour les tests.

Voici la main.ts fichier qui crée un microservice.

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { Transport } from '@nestjs/common/enums/transport.enum';

async function bootstrap() {
  const app = await NestFactory.createMicroservice(AppModule, {
    transport: Transport.REDIS,
    options: {
      url: 'redis://localhost:6379',
    },
  });
  await app.listen(() => console.log('MoviesService is running.'));
}
bootstrap();

Et l'un des contrôleurs:

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @MessagePattern({ cmd: 'LIST_MOVIES' })
  listMovies(): string[] {
    return ['Pulp Fiction', 'Blade Runner', 'Hatred'];
  }
}

Maintenant - dans le microservice, vous déclarez à quels types d'événements les contrôleurs doivent réagir (@MessagePattern). Dans le service "normal", vous effectuez cette opération dans le contrôleur lorsque vous souhaitez demander quelque chose à d'autres microservices (le main.ts est l'exemple le plus simple que vous obtenez lorsque vous créez un nouveau projet à l'aide de @nestjs/cli.

Le code du contrôleur:

@Controller()
export class AppController {
  private readonly client: ClientProxy;

  constructor(private readonly appService: AppService) {
    this.client = ClientProxyFactory.create({
      transport: Transport.REDIS,
      options: {
        url: 'redis://localhost:6379',
      },
    });
  }

  @Get()
  listMovies() {
    const pattern = { cmd: 'LIST_MOVIES' };

    return this.client.send<string[]>(pattern, []);
  }
}

Aussi longtemps qu'un client est connecté à la même couche de transport que le microservice - ils peuvent se parler en utilisant le @MessagePattern.

Pour un code plus agréable, vous pouvez déplacer le this.client part d'un constructeur vers un fournisseur, puis utilisez l'injection de dépendance en déclarant le fournisseur dans le module.

23
Tomasz Gałkowski