Microservices with NestJS
Introduction to microservices architecture and how to build microservices using NestJS with gRPC or message queues (e.g., RabbitMQ, Kafka).
Setting up a NestJS Project for Microservices
Introduction
This document outlines the steps involved in setting up a NestJS project for a microservices architecture. We'll cover project creation using the Nest CLI, configuration for microservices, and initial dependencies. This guide assumes you have Node.js and npm (or yarn) installed.
Creating a New NestJS Project using the Nest CLI
The Nest CLI provides a simple way to scaffold a new NestJS project. To create a new project, run the following command in your terminal:
nest new my-microservice-project
This command will create a new directory named my-microservice-project
and initialize a basic NestJS application. The CLI will prompt you to choose a package manager (npm or yarn). Select your preferred package manager.
Once the project is created, navigate into the project directory:
cd my-microservice-project
Configuring the Project for a Microservices Architecture
Configuring a NestJS project for microservices involves adjusting the main application module and adding necessary dependencies. Here's a breakdown of the steps:
1. Package Structure
A good package structure is crucial for maintainability. Consider a structure like this:
src/
main.ts
(Entry point for the microservice)app.module.ts
(Main application module)app.controller.ts
(Basic controller - can be removed or repurposed)app.service.ts
(Basic service - can be removed or repurposed)[feature-module]/
(e.g.,user/
,product/
)[feature].module.ts
[feature].controller.ts
[feature].service.ts
shared/
(Shared components, DTOs, etc.)dto/
interfaces/
test/
(Unit and E2E tests)nest-cli.json
(Nest CLI configuration)package.json
(Dependencies and scripts)tsconfig.json
(TypeScript configuration)
2. Initial Dependencies
Install the required dependencies for microservices. Common choices include:
@nestjs/microservices
: Provides core microservices functionality.@nestjs/platform-tcp
,@nestjs/platform-redis
,@nestjs/platform-grpc
,@nestjs/platform-nats
: Platform-specific transport layers for microservices. Choose one or more based on your needs. TCP is a simple starting point, Redis is good for pub/sub, gRPC for high-performance contracts, and NATS for lightweight messaging.reflect-metadata
: Required for NestJS's dependency injection. Should already be present, but ensure it is.- (Optional)
class-validator
,class-transformer
: For validation of request payloads.
Install these using npm or yarn. For example, using npm with TCP and class-validator:
npm install --save @nestjs/microservices @nestjs/platform-tcp reflect-metadata class-validator class-transformer
3. Configuring the Main Application (main.ts
)
Modify main.ts
to start the application as a microservice. Choose your desired transport strategy. Here's an example using TCP:
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';
async function bootstrap() {
const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
transport: Transport.TCP,
options: {
host: 'localhost',
port: 3001,
},
});
app.listen();
}
bootstrap();
This code initializes the Nest application as a microservice using the TCP transport. It listens on localhost
and port 3001
. Adjust these values as needed.
Here's an example using Redis transport:
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';
async function bootstrap() {
const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
transport: Transport.REDIS,
options: {
host: 'localhost',
port: 6379,
},
});
app.listen();
}
bootstrap();
This code initializes the Nest application as a microservice using the Redis transport. It assumes a Redis server is running on localhost
and port 6379
. Adjust these values as needed.
4. Modify the app.module.ts
Generally, in a microservice context, you would structure your application with feature-specific modules. The `AppModule` becomes a container for these feature modules.
import { Module } from '@nestjs/common';
import { UserModule } from './user/user.module';
import { ProductModule } from './product/product.module';
@Module({
imports: [UserModule, ProductModule],
controllers: [], // Controllers should reside in feature modules
providers: [], // Providers (services) should reside in feature modules
})
export class AppModule {}
This example imports `UserModule` and `ProductModule`, which represent different functionalities of your microservice.
Next Steps
With the basic project structure and configuration in place, you can now start building your microservice logic. Consider the following next steps:
- Define your message contracts (DTOs).
- Implement controllers and services to handle incoming messages.
- Add logging and monitoring.
- Implement unit and integration tests.
- Explore advanced features like message queues, event sourcing, and CQRS.