NestJS 마스터 시리즈 8화. 비동기 프로그래밍과 RxJS – NestJS의 Reactive 구조를 이해하라
"Promise로는 충분하지 않다. NestJS가 RxJS를 기본으로 채택한 이유"
메타 설명 (SEO 최적화용)
NestJS에서 비동기 프로그래밍을 어떻게 처리하는지, Promise와 RxJS Observable의 차이, Reactive Stream 기반 설계 철학을 실전 예제와 함께 설명합니다.
비동기 처리, 그 이상이 필요한 순간
Node.js는 기본적으로 비동기 이벤트 루프 위에서 동작한다. 하지만 복잡한 백엔드 로직에서는 단순한 Promise로 처리하기에는 한계가 있다.
NestJS는 이런 구조적 복잡성을 해결하기 위해 RxJS 기반의 비동기 흐름 처리 시스템을 내장하고 있다.
NestJS는 내부적으로 모든 비동기 처리를 Observable 기반으로 통합할 수 있도록 설계되어 있다.
Promise vs Observable – 무엇이 다른가
비교 항목 Promise Observable (RxJS)
동작 횟수 | 한 번 | 여러 번 (스트림) |
취소 가능성 | 불가능 | 가능 |
연산 체이닝 | .then() | .pipe() |
에러 처리 | .catch() | catchError() |
다중 처리 | 불편 | 매우 유연 (combineLatest, forkJoin 등) |
Promise는 단일 값 비동기에 적합하다면, Observable은 연속적, 조합적, 반응형 데이터 흐름에 적합하다.
NestJS에서 Observable 지원 방식
NestJS는 @Controller에서 반환값으로 Observable을 사용할 수 있도록 기본 지원한다.
예를 들어 rxjs 라이브러리의 of()를 이용해 바로 Observable 응답을 만들 수 있다.
import { Controller, Get } from '@nestjs/common';
import { of } from 'rxjs';
@Controller('ping')
export class PingController {
@Get()
getPing() {
return of({ message: 'pong' });
}
}
NestJS는 이 Observable을 자동으로 subscribe하고, 그 결과값을 응답으로 반환한다.
실전 예제 – 외부 API 호출 시 Observable 사용하기
import { Injectable, HttpService } from '@nestjs/common';
import { map } from 'rxjs/operators';
@Injectable()
export class WeatherService {
constructor(private httpService: HttpService) {}
getForecast(city: string) {
return this.httpService
.get(`https://api.weatherapi.com/v1/current.json?q=${city}`)
.pipe(map(res => res.data));
}
}
- HttpService는 내부적으로 axios를 Observable로 래핑
- pipe()와 map()을 통해 응답 처리
RxJS 핵심 연산자 정리
연산자 설명
map | 값을 변환 |
mergeMap, switchMap | 내부 Observable을 평탄화(flatten) |
catchError | 에러 처리 |
filter, take, tap | 흐름 제어 및 중간 로깅 |
이 연산자들은 단순한 데이터 흐름을 넘어서 비동기 조합, 조건 분기, 예외 처리까지 모두 포함한다.
언제 RxJS를 쓰는 것이 적합한가?
- 외부 API 요청을 여러 개 병렬로 보낼 때
- WebSocket이나 SSE처럼 실시간 스트림이 필요한 경우
- 내부 마이크로서비스 간 메시징 시스템을 구성할 때
- 복잡한 조건 분기와 흐름 제어가 필요한 비동기 처리
마무리 인사이트
NestJS는 단순한 Promise 기반 백엔드를 넘어, Reactive 패러다임에 기반한 구조적 확장성을 갖추고 있다.
RxJS는 처음엔 낯설지만, 구조적으로 설계된 API 흐름을 만들고자 한다면 반드시 익혀야 하는 도구다.
- 단일 응답 → Promise
- 연속적인 이벤트/요청 → Observable
- 복잡한 처리 로직 → RxJS 조합 연산자
RxJS는 단순한 도구가 아니라, 비동기 흐름을 설계하는 새로운 언어다.
다음 회차 예고
NestJS 마스터 시리즈 9화. 예외 처리 전략 – 오류는 숨기지 말고 설계하라
HTTPException, ExceptionFilter, 커스텀 에러 구조까지 다룹니다.