Integración de NATS en una Arquitectura de Microservicios con NestJS, Docker y PostgreSQL
Introducción
En el mundo del desarrollo de software, los microservicios han ganado popularidad debido a su capacidad para dividir aplicaciones grandes y complejas en partes más pequeñas y manejables. En este blog, exploraremos cómo integrar un servidor NATS (Neural Autonomic Transport System) en una arquitectura de microservicios utilizando NestJS, Docker y PostgreSQL. Para hacerlo más tangible, utilizaremos un caso de uso real de una aplicación de gestión de pedidos.
Caso de Uso: Aplicación de Gestión de Pedidos
Imaginemos que estamos construyendo una aplicación de gestión de pedidos que incluye múltiples servicios, como el servicio de pedidos, el servicio de inventario y el servicio de notificaciones. Estos servicios deben comunicarse entre sí de manera eficiente y confiable. Aquí es donde NATS entra en juego, proporcionando un sistema de mensajería rápida y de bajo retardo.
Arquitectura de la Aplicación
Nuestra aplicación de gestión de pedidos tendrá la siguiente arquitectura:
- Servicio de Pedidos: Gestiona la creación, actualización y eliminación de pedidos.
- Servicio de Inventario: Mantiene el inventario de productos y actualiza las existencias según los pedidos.
- Servicio de Notificaciones: Envía notificaciones a los usuarios sobre el estado de sus pedidos.
Configuración de Docker
Primero, configuramos Docker para orquestar nuestros servicios. Creamos un archivo Dockerfile
para nuestro servicio NestJS y un archivo docker-compose.yml
para definir y ejecutar múltiples contenedores Docker.
FROM node:14
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm", "run", "start:prod"]
Docker Compose
version: '3'
services:
postgres:
image: postgres:latest
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: orders
ports:
- "5432:5432"
volumes:
- postgres-data:/var/lib/postgresql/data
nats:
image: nats:latest
ports:
- "4222:4222"
orders:
build: .
environment:
DATABASE_HOST: postgres
DATABASE_PORT: 5432
DATABASE_USER: user
DATABASE_PASSWORD: password
DATABASE_NAME: orders
NATS_SERVER: nats://nats:4222
depends_on:
- postgres
- nats
ports:
- "3000:3000"
volumes:
postgres-data:
Configuración de NestJS
Ahora configuramos nuestro proyecto NestJS para que interactúe con NATS y PostgreSQL.
Instalación de Dependencias
npm install @nestjs/microservices nats @nestjs/typeorm typeorm pg
Claro, aquí tienes un ejemplo de cómo se podría escribir un blog sobre la integración de un servidor NATS en una configuración de microservicios utilizando NestJS, Docker y PostgreSQL, con un caso de uso real.
Integración de NATS en una Arquitectura de Microservicios con NestJS, Docker y PostgreSQL
Introducción
En el mundo del desarrollo de software, los microservicios han ganado popularidad debido a su capacidad para dividir aplicaciones grandes y complejas en partes más pequeñas y manejables. En este blog, exploraremos cómo integrar un servidor NATS (Neural Autonomic Transport System) en una arquitectura de microservicios utilizando NestJS, Docker y PostgreSQL. Para hacerlo más tangible, utilizaremos un caso de uso real de una aplicación de gestión de pedidos.
Caso de Uso: Aplicación de Gestión de Pedidos
Imaginemos que estamos construyendo una aplicación de gestión de pedidos que incluye múltiples servicios, como el servicio de pedidos, el servicio de inventario y el servicio de notificaciones. Estos servicios deben comunicarse entre sí de manera eficiente y confiable. Aquí es donde NATS entra en juego, proporcionando un sistema de mensajería rápida y de bajo retardo.
Arquitectura de la Aplicación
Nuestra aplicación de gestión de pedidos tendrá la siguiente arquitectura:
- Servicio de Pedidos: Gestiona la creación, actualización y eliminación de pedidos.
- Servicio de Inventario: Mantiene el inventario de productos y actualiza las existencias según los pedidos.
- Servicio de Notificaciones: Envía notificaciones a los usuarios sobre el estado de sus pedidos.
Configuración de Docker
Primero, configuramos Docker para orquestar nuestros servicios. Creamos un archivo Dockerfile
para nuestro servicio NestJS y un archivo docker-compose.yml
para definir y ejecutar múltiples contenedores Docker.
Dockerfile para el servicio NestJS
FROM node:14
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm", "run", "start:prod"]
Docker Compose
version: '3'
services:
postgres:
image: postgres:latest
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: orders
ports:
- "5432:5432"
volumes:
- postgres-data:/var/lib/postgresql/data
nats:
image: nats:latest
ports:
- "4222:4222"
orders:
build: .
environment:
DATABASE_HOST: postgres
DATABASE_PORT: 5432
DATABASE_USER: user
DATABASE_PASSWORD: password
DATABASE_NAME: orders
NATS_SERVER: nats://nats:4222
depends_on:
- postgres
- nats
ports:
- "3000:3000"
volumes:
postgres-data:
Configuración de NestJS
Ahora configuramos nuestro proyecto NestJS para que interactúe con NATS y PostgreSQL.
Instalación de Dependencias
npm install @nestjs/microservices nats @nestjs/typeorm typeorm pg
Configuración del Microservicio con NATS
Configuramos el microservicio en el archivo app.module.ts
para que use NATS como sistema de mensajería.
import { Module } from '@nestjs/common';
import { ClientsModule, Transport } from '@nestjs/microservices';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [
ClientsModule.register([
{
name: 'NATS_SERVICE',
transport: Transport.NATS,
options: {
url: process.env.NATS_SERVER,
},
},
]),
TypeOrmModule.forRoot({
type: 'postgres',
host: process.env.DATABASE_HOST,
port: parseInt(process.env.DATABASE_PORT, 10),
username: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD,
database: process.env.DATABASE_NAME,
entities: [__dirname + '/**/*.entity{.ts,.js}'],
synchronize: true,
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Uso del Servicio NATS en un Controlador
En el controlador, usamos NATS para enviar y recibir mensajes.
import { Controller, Get } from '@nestjs/common';
import { ClientProxy, Client } from '@nestjs/microservices';
import { Observable } from 'rxjs';
@Controller()
export class AppController {
@Client({ transport: Transport.NATS, options: { url: process.env.NATS_SERVER } })
private client: ClientProxy;
@Get()
getHello(): Observable<string> {
return this.client.send<string>({ cmd: 'hello' }, {});
}
}
Integración con PostgreSQL
Configuramos TypeORM para interactuar con PostgreSQL.
Configuración de TypeORM
import { TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'postgres',
host: process.env.DATABASE_HOST,
port: parseInt(process.env.DATABASE_PORT, 10),
username: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD,
database: process.env.DATABASE_NAME,
entities: [__dirname + '/**/*.entity{.ts,.js}'],
synchronize: true,
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Conclusión
Con esta configuración, hemos logrado integrar un servidor NATS en una arquitectura de microservicios utilizando NestJS, Docker y PostgreSQL. Esta integración permite que nuestros servicios se comuniquen de manera eficiente y escalable, lo que es crucial para aplicaciones modernas de microservicios. La configuración de Docker facilita el despliegue y la gestión de cada componente, asegurando que nuestra aplicación sea fácil de mantener y escalar.