NestJS로 마이크로서비스 아키텍처 구축하기: Express와의 차이점

작성일 :

NestJS로 마이크로서비스 아키텍처 구축하기: Express와의 차이점

NestJS는 Node.js 환경에서 서버 사이드 애플리케이션을 개발하는 데 최적화된 프레임워크입니다. NestJS는 Angular에서 영감을 받았으며, 폴더 구조와 아키텍처에서도 많은 유사점을 확인할 수 있습니다. 반면에, Express는 경량 및 유연성으로 잘 알려진 Node.js 기반의 웹 프레임워크입니다. 이번 글에서는 NestJS와 Express의 차이점 및 NestJS를 사용하여 마이크로서비스 아키텍처를 구축하는 방법에 대해 설명하겠습니다.

NestJS와 Express의 차이점

구조와 패턴

Express는 미들웨어를 기반으로 하는 간단한 요청/응답 라이브러리로 시작되었습니다. Express 애플리케이션은 일반적으로 루트 파일과 다양한 라우터 파일들로 구성되며, 개발자가 직접 디렉터리 구조와 파일을 관리하기에 많은 자유도가 있습니다. 그러나 자유도가 높은 만큼 코드가 복잡해지거나 일관성을 잃기 쉬운 단점도 있습니다.

NestJS는 모듈화된 애플리케이션 구조를 사용합니다. 이는 클린 아키텍처와 사실상 일치하여 각 모듈이 독립적으로 동작하고 쉽게 테스트할 수 있게 합니다. 또한, NestJS는 Dependency Injection(DI)를 기본적으로 지원하여 서비스 간의 의존성을 쉽게 관리할 수 있습니다.

타입스크립트 지원

NestJS는 기본적으로 타입스크립트를 지원합니다. 이는 코드의 안전성을 높여주고, 컴파일 시점에 오류를 잡아주는 데 큰 도움이 됩니다. 반면에, Express는 자바스크립트를 기본적으로 사용하며, 타입스크립트를 사용하려면 추가적인 설정이 필요합니다.

내장 기능

Express는 경량 프레임워크로서 최소한의 기능만을 제공합니다. 미들웨어, 라우터, 뷰 엔진 등은 전부 별도의 라이브러리로 추가해야 합니다. 반면, NestJS는 실시간 애플리케이션을 위한 WebSocket 통합, GraphQL 통합, 마이크로서비스 지원 등 다양한 내장 기능을 제공하여 개발자가 더 적은 노력으로 고급 기능을 구현할 수 있도록 돕습니다.

NestJS를 사용하여 마이크로서비스 아키텍처 구축하기

마이크로서비스란?

마이크로서비스 아키텍처는 단일 애플리케이션을 작고 독립적인 서비스로 분해하는 아키텍처 스타일입니다. 이러한 서비스는 독립적으로 개발, 배포, 확장될 수 있어 유지보수 및 확장성이 뛰어납니다.

마이크로서비스 주요 구성 요소

마이크로서비스 아키텍처를 구성하는 주요 요소들은 다음과 같습니다:

  • 서비스 디스커버리: 각 마이크로서비스의 위치를 파악하는 기능입니다. 이 기능이 없으면, 서비스 간의 통신을 관리하기 매우 어렵습니다.

  • API 게이트웨이: 클라이언트 요청을 적절한 마이크로서비스로 라우팅하고, 인증 및 부하 분산 등의 기능을 제공합니다.

  • 폴백 및 장애 처리: 서비스 간 요청에 실패했을 때 대체 경로를 설정하거나, 실패를 감지하고 적절히 처리합니다.

NestJS로 마이크로서비스 구현하기

프로젝트 설정

먼저 NestJS CLI를 사용하여 새로운 프로젝트를 생성합니다.

bash
nest new microservice-app

네트워크 통신을 위한 마이크로서비스 모듈을 생성합니다. NestJS는 다양한 마이크로서비스 통신 패턴을 지원하며, 그 중 일부는 RabbitMQ, Kafka, gRPC 등이 있습니다.

bash
nest generate module users
nest generate service users

마이크로서비스 설정

다음으로, 마이크로서비스 설정을 작성합니다. 예를 들어, RabbitMQ를 사용하여 마이크로서비스를 설정할 수 있습니다.

typescript
import { NestFactory } from '@nestjs/core';
import { Transport, MicroserviceOptions } from '@nestjs/microservices';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
    transport: Transport.RMQ,
    options: {
      urls: ['amqp://localhost:5672'],
      queue: 'main_queue',
      queueOptions: {
        durable: false
      },
    },
  });
  app.listen(() => console.log('Microservice is listening'));
}
bootstrap();

서비스 간 통신

다음으로, 서비스 간 통신을 설정합니다. NestJS는 ClientProxy 클래스를 사용하여 다른 마이크로서비스에 메시지를 보낼 수 있습니다.

typescript
import { Injectable } from '@nestjs/common';
import { ClientProxy, Transport, Client } from '@nestjs/microservices';

@Injectable()
export class AppService {
  @Client({
    transport: Transport.RMQ,
    options: {
      urls: ['amqp://localhost:5672'],
      queue: 'other_queue',
      queueOptions: {
        durable: false
      },
    },
  })
  private client: ClientProxy;

  async sendMessage(pattern: string, data: any) {
    return this.client.send(pattern, data).toPromise();
  }
}

결론

NestJS는 구조화된 아키텍처와 강력한 내부 기능을 제공하여 마이크로서비스를 구축하기에 매우 적합한 프레임워크입니다. 반면, Express는 빠르고 간단한 프로젝트에 적합하며, 자유롭고 유연하게 사용할 수 있습니다. 요구사항에 따라 적절한 프레임워크를 선택하여 개발을 진행하면 됩니다.