Nodejs

 

 

1. NestJS 마이크로서비스 통신 — 주문 → 결제 → 알림 (1/3)

 

 

 

 

이 문서는 강의 내용을 바탕으로 마이크로서비스 간 결제/알림 흐름을 정리한 1편입니다. 핵심은 Order → Payment → Notification 서비스 간 메시지 통신입니다.

1. 전체 시나리오

  1. 사용자가 Order 서비스(HTTP)로 주문 생성 요청을 보냅니다.

  2. Order 서비스는 내부 로직 처리 후 Payment 서비스에 TCP RPC(make_payment)를 호출합니다.

  3. Payment 서비스는 결제를 처리하고, 완료되면 Notification 서비스에 TCP RPC(send_payment_notification)를 호출합니다.

  4. Notification 서비스는 알림을 생성한 뒤, 이벤트(delivery_started)를 Order 서비스에 emit 하여 주문 상태를 업데이트합니다.

 

 

2. Order → Payment (결제 시도)

Order 서비스에서 결제 처리를 요청하는 부분입니다.

// order.service.ts (발췌)
async processPayment(orderId: string, payment: PaymentDto, userEmail: string) {
  const resp = await lastValueFrom(
    this.paymentService.send(
      { cmd: 'make_payment' }, // RPC 호출 패턴
      { ...payment, userEmail, orderId },
    ),
  );
  return resp;
}
  • ClientProxy.send()를 통해 Payment 서비스로 TCP RPC 요청.

  • payload에 orderId, userEmail, payment 정보를 함께 전달.

 

 

3. Payment (결제 처리)

Payment 서비스는 make_payment 메시지를 받아 DB에 결제 정보를 저장하고, 성공 시 Notification 서비스로 메시지를 전송합니다.

// payment.controller.ts (발췌)
@MessagePattern({ cmd: 'make_payment' })
async makePayment(@Payload() payload: MakePaymentDto) {
  return this.paymentService.makePayment(payload);
}

// payment.service.ts (발췌)
async makePayment(payload: MakePaymentDto) {
  const result = await this.paymentRepository.save(payload);
  await this.updatePaymentStatus(result.id, PaymentStatus.approved);

  // Notification 서비스 호출
  this.sendNotification(payload.orderId, payload.userEmail);
  return this.paymentRepository.findOneBy({ id: result.id });
}

async sendNotification(orderId: string, to: string) {
  return await lastValueFrom(
    this.notificationService.send(
      { cmd: 'send_payment_notification' }, // RPC 패턴
      { to, orderId },
    ),
  );
}
  • @MessagePattern으로 Payment 서비스가 메시지를 수신.

  • 결제 DB 저장 → 상태 업데이트.

  • notificationService.send() 호출하여 Notification 서비스에 RPC 요청.

➡️ 다음 문서(2/3)에서는 Notification 서비스의 처리Order 서비스로의 이벤트 emit 과정을 설명합니다.

 

 

 

2.NestJS 마이크로서비스 통신 — 주문 → 결제 → 알림 (2/3)

다음 Notification 서비스의 역할과 Order 서비스로의 이벤트 전달을 설명합니다.

 

1. Notification 서비스 역할

Payment 서비스에서 결제 성공 메시지를 받으면 Notification 서비스가 이를 처리합니다.

// notification.controller.ts (발췌)
@MessagePattern({ cmd: 'send_payment_notification' })
async sendPaymentNotification(@Payload() payload: SendPaymentNotificationDto) {
  return this.notificationService.sendPaymentNotification(payload);
}
  • Payment → Notification 통신은 RPC (Request-Response) 패턴.

  • 결제 성공 시 send_payment_notification 메시지를 수신.

 

2. Notification 서비스 내부 처리

// notification.service.ts (발췌)
async sendPaymentNotification(data: SendPaymentNotificationDto) {
  // 1. Notification DB에 저장
  const notification = await this.createNotifiction(data.to);

  // 2. 이메일 전송 (mock)
  await this.sendEmail();

  // 3. 상태 업데이트
  await this.updateNotificationStatus(
    notification._id.toString(),
    NotificationStatus.sent,
  );

  // 4. Order 서비스에 이벤트 전달
  this.sendDeliveryStartedMessage(data.orderId);

  return this.notificationModel.findById(notification._id);
}

sendDeliveryStartedMessage(id: string) {
  this.orderMicroservice.emit(
    { cmd: 'delivery_started' }, // 이벤트 패턴
    { id },
  );
}
  • DB 저장: MongoDB에 알림 데이터(from, to, subject, content) 저장.

  • 이메일 발송: 실제 구현 대신 setTimeout으로 모킹.

  • 상태 업데이트: pending → sent.

  • Order 서비스에 이벤트 emit: delivery_started 메시지 송출.

 

3. 이벤트 기반 통신

  • send_payment_notification: RPC (요청-응답).

  • delivery_started: Event (단방향 알림).

➡️ 다음 문서(3/3)에서는 Order 서비스가 delivery_started 이벤트를 받아 상태를 갱신하는 과정을 설명합니다.

 

 

 

3. NestJS 마이크로서비스 통신 — 주문 → 결제 → 알림 (3/3)

이 문서는 마지막 3편으로, Order 서비스가 Notification의 이벤트를 받아 주문 상태를 갱신하는 과정을 설명합니다.

 

1. Order 서비스에서 이벤트 수신

// order.controller.ts (발췌)
@EventPattern({ cmd: 'delivery_started' })
async handleDeliveryStarted(@Payload() payload: { id: string }) {
  return this.orderService.updateStatus(payload.id, OrderStatus.delivering);
}
  • Notification 서비스가 emit한 이벤트(delivery_started)를 수신.

  • @EventPattern은 응답을 요구하지 않는 단방향 이벤트를 처리.

 

2. Order 상태 업데이트

// order.service.ts (발췌)
async updateStatus(id: string, status: OrderStatus) {
  await this.orderRepository.update({ id }, { status });
  return this.orderRepository.findOneBy({ id });
}
  • DB에서 해당 주문의 상태를 delivering으로 변경.

  • 이후 클라이언트가 주문 상태를 조회하면 업데이트된 상태가 확인됨.

 

3. 전체 플로우 다시 정리

  1. Order 서비스: 주문 생성 시 Payment RPC 호출.

  2. Payment 서비스: 결제 처리 후 Notification RPC 호출.

  3. Notification 서비스: 알림 생성 후 Order 서비스로 이벤트 emit.

  4. Order 서비스: 이벤트 수신 후 상태를 delivering으로 갱신.

 

4. 포인트

  • RPC vs Event 차이: RPC는 요청-응답 기반, Event는 단방향 알림.

  • 서비스 간 의존성: Order는 Payment/Notification 모두와 통신하지만, 직접적인 결합을 줄이고 TCP 메시지 패턴으로 느슨하게 연결됨.

  • 확장성: Notification 서비스는 이메일 외에도 SMS, Push 알림 등으로 확장 가능.

✅ 이렇게 해서 "주문 → 결제 → 알림" 마이크로서비스 간 통신의 흐름이 완성됩니다.

 

 

 

 

about author

PHRASE

Level 60  라이트

벼슬을 하는 사람이 지켜야 할 세 가지 덕목이 있다. 첫째 청(淸), 즉 결백해야 한다. 둘째 신(愼), 즉 몸을 삼가여 예의에 따르는 일이다. 셋째는 근(勤), 즉 자기가 맡은 직무에 충실하고 부지런해야 하는 것이다. 여씨동몽훈(呂氏童蒙訓)에 있는 말. -소학

댓글 ( 0)

댓글 남기기

작성