NestJS는 내장 microservice 지원을 갖추고 있습니다 — HTTP 대신 다양한 transport(TCP, Redis, NATS, RabbitMQ, Kafka, gRPC)를 통해 통신하는 microservice로 실행될 수 있으며, 일관된 메시지 기반 프로그래밍 모델을 사용합니다. 동일한 NestJS 구조(module, service, DI)가 적용되며, transport와 메시지 패턴만 바뀝니다.
microservice 생성
// microservice는 HTTP 대신 transport에서 수신 대기
const app = await NestFactory.createMicroservice(AppModule, {
transport: Transport.TCP, // 또는 REDIS, NATS, RMQ, KAFKA, GRPC
options: { host: "0.0.0.0", port: 3001 },
});
await app.listen();
message pattern 대 event pattern
@Controller()
export class MathController {
// 요청-응답: 메시지에 응답하고 결과를 반환 (RPC 스타일)
@MessagePattern({ cmd: "sum" })
sum(data: number[]): number {
return data.reduce((a, b) => a + b, 0); // 호출자가 이 결과를 기다림
}
// 이벤트 기반: 이벤트에 반응, 응답 없음 (fire-and-forget)
@EventPattern("order_created")
handleOrderCreated(data: OrderDto) {
this.processOrder(data); // 그냥 반응; 아무것도 반환 안 함
}
}
두 가지 통신 스타일: 요청-응답을 위한 @MessagePattern(호출자가 결과를 기다림, RPC처럼)과 이벤트를 위한 @EventPattern(fire-and-forget, 분리됨 — 발행자가 기다리지 않음).
다른 microservice 호출 (클라이언트)
@Injectable()
export class AppService {
constructor(@Inject("MATH_SERVICE") private client: ClientProxy) {}
async getSum() {
// send() → 요청-응답 (결과의 Observable 반환)
return this.client.send({ cmd: "sum" }, [1, 2, 3]);
// emit() → 이벤트 발행 (응답 없음)
this.client.emit("order_created", orderData);
}
}
ClientProxy(ClientsModule을 통해 구성됨)는 다른 service에 메시지/이벤트를 보냅니다 — 요청-응답에는 send(), 이벤트에는 emit().
하이브리드 애플리케이션
// 앱은 HTTP와 microservice transport를 동시에 제공할 수 있음
const app = await NestFactory.create(AppModule);
app.connectMicroservice({ transport: Transport.RMQ, options: {...} });
await app.startAllMicroservices();
await app.listen(3000); // HTTP도
transport 선택이 중요합니다
TCP → 간단한 직접 service 간 통신
Redis/NATS → 경량 pub/sub 메시징
RabbitMQ/Kafka → 견고한 message queue/stream (내구성, 재시도, 분리)
gRPC → 고성능, 강타입 RPC (protobuf)
→ 비동기 message broker(RMQ/Kafka)는 분리와 복원력을; gRPC는 속도+타입을 제공.
왜 중요한가
NestJS의 내장 microservice 지원은 의미가 큽니다. 동일한 친숙한 NestJS 구조(module, provider, DI, decorator)를 사용하면서 HTTP를 메시지 기반 transport로 교체하여 분산 시스템을 구축할 수 있게 하기 때문입니다 — 큰 생산성과 일관성의 이점입니다.
확장 가능한 시스템을 설계하는 데 이를 이해하는 것이 중요합니다: message-pattern(요청-응답) 대 event-pattern(fire-and-forget) 구분은 근본적인 microservice 통신 선택에 직접 매핑됩니다 — 동기적 RPC 스타일 호출 대 비동기, 분리된 이벤트(후자는 message broker를 통해 microservice를 견고하게 만드는 복원력과 느슨한 결합을 제공).
microservice를 생성하고, 메시지/이벤트 핸들러를 정의하고, ClientProxy를 통해 다른 service를 호출하고, 하이브리드 HTTP+microservice 앱을 구축하고, transport를 선택하는(경량 pub/sub 대 Kafka/RabbitMQ 같은 내구성 있는 queue 대 고성능 gRPC) 방법을 아는 것은 분산 백엔드를 설계하는 데 가치 있는 시니어 수준 지식입니다.
microservice는 실제 복잡성을 더하지만(그리고 항상 모놀리스보다 옳은 선택은 아니지만), NestJS는 구현을 깔끔하고 일관되게 만들어, 대규모 분산 NestJS 시스템을 구축하는 중요한 아키텍처 주제로 만듭니다.
