Introduction : Pourquoi TypeScript est idéal pour les microservices
L'architecture microservices est devenue la norme pour construire des applications complexes, évolutives et résilientes. TypeScript, grâce à son typage strict, son écosystème riche et sa prise en charge de l'asynchrone, est l'un des meilleurs langages pour implémenter des microservices. Il permet d'écrire un code plus facile à refactoriser, tester et documenter, ce qui est crucial lors de la division d'un système en dizaines de services indépendants.
Dans cet article, nous analyserons les principes architecturaux, construirons un microservice simple avec NestJS, configurerons la communication inter-services via RabbitMQ et empaquèterons le tout dans Docker Compose. Vous obtiendrez une base pratique prête à l'emploi pour démarrer.
Architecture des microservices en TypeScript
Une architecture correcte est la clé du succès. Pour les microservices TypeScript, on distingue trois couches clés :
- Couche de transport — responsable de la réception et de l'envoi des requêtes (HTTP, gRPC, files de messages).
- Logique métier — fonctions pures et services indépendants du framework.
- Couche de données — repositories et ORM (TypeORM, Prisma).
Chaque microservice doit être autonome : avoir sa propre base de données, son CI/CD et sa logique de déploiement. La communication entre services est généralement réalisée via des files asynchrones (RabbitMQ, Kafka) ou des appels synchrones (gRPC).
Pratique : Création d'un microservice avec NestJS
Étape 1 : Initialisation du projet
Installez le CLI NestJS et créez un nouveau projet :
npm i -g @nestjs/cli
nest new user-service --package-manager npm
cd user-service
Étape 2 : Ajout de la prise en charge des microservices
NestJS dispose d'une prise en charge intégrée des transporteurs de microservices. Installons RabbitMQ :
npm install @nestjs/microservices amqplib amqp-connection-manager
Créons main.ts, qui lance le service en tant que microservice :
import { NestFactory } from '@nestjs/core';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.createMicroservice<MicroserviceOptions>(
AppModule,
{
transport: Transport.RMQ,
options: {
urls: ['amqp://localhost:5672'],
queue: 'user_queue',
queueOptions: { durable: false },
},
},
);
await app.listen();
}
bootstrap();
Étape 3 : Implémentation du contrôleur
Créons un contrôleur simple qui traite les messages de la file :
import { Controller } from '@nestjs/common';
import { MessagePattern, Payload } from '@nestjs/microservices';
@Controller()
export class UserController {
@MessagePattern('user.create')
createUser(@Payload() data: { name: string; email: string }): string {
// La logique métier de création d'utilisateur devrait être ici
return `Utilisateur ${data.name} créé`;
}
}
Désormais, n'importe quel service peut envoyer un message dans la file user_queue avec le pattern user.create et obtenir une réponse.
Communication inter-services : synchrone et asynchrone
Synchrone : gRPC
Pour les systèmes à forte charge nécessitant un typage strict et une faible latence, utilisez gRPC. Installez le package :
npm install @nestjs/microservices @grpc/grpc-js @grpc/proto-loader
Définissez le fichier .proto :
syntax = "proto3";
package user;
service UserService {
rpc GetUser (UserId) returns (User);
}
message UserId { int32 id = 1; }
message User { string name = 1; string email = 2; }
Dans le contrôleur, utilisez le décorateur @GrpcMethod pour traiter la requête.