NestJS - 개념 및 기본 사용방법

왜 Nest.js를 사용할까?


logo

> NestJS의 아키텍처 계층

보통 node.js로 백엔드 개발을 할때 가장 유명한 프레임워크는 Express.js이다. 하지만 Express.js는 정해진 아키텍처가 없기에 개발자마다 다른 구조로 작성하게 되는 장점이자, 단점인 유연성으로 아키텍처가 잘 구조화된 프로젝트 일지라도 프로젝트가 커지면 커질수록 유지보수가 어려워지고, 확장성이 떨어진다.
이러한 문제를 해결하기 위해 Nest.js가 등장했다.

Nest.js는 Angular의 아키텍처와 구조를 기반으로 하며, 모듈화, 의존성 주입, 데코레이터 등의 개념을 도입하여 코드의 구조를 명확하게 하고 유지보수성을 높인다.

또한, Nest.js는 Express.js를 기반으로 하기 때문에 Express.js의 기능을 모두 사용할 수 있으며, 추가적으로 WebSocket, GraphQL, Microservices 등의 기능을 제공한다. NestJS는 TypeScript를 사용하여 효율적이고 확장 가능한 Node.js 서버 사이드 애플리케이션을 구축하기 위한 프레임워크이다.

NestJS의 핵심 요소


구분 내용
주요 특징
  • TypeScript 기반
  • 모듈화 아키텍처
  • 의존성 주입
  • 데코레이터 기반
  • 확장성
주요 기능
  • REST API 구축
  • GraphQL 지원
  • WebSocket 지원
  • 마이크로서비스 아키텍처
  • CLI 도구 제공
  • 테스트 도구 내장
  • ORM 지원 (TypeORM, Sequelize 등)
사용 사례
  • 대규모 웹 애플리케이션
  • 마이크로서비스 아키텍처
  • 실시간 애플리케이션 (채팅, 게임 등)
  • 백엔드 서버 개발
  • 클라우드 기반 애플리케이션
장점
  • 체계적인 아키텍처 구조
  • TypeScript를 통한 타입 안정성
  • 풍부한 문서화와 활발한 커뮤니티
  • 확장성과 유지보수성이 뛰어남
  • 다양한 기능과 라이브러리 통합 용이
단점
  • 학습 곡선이 상대적으로 높음
  • 초기 설정 및 구성이 복잡할 수 있음
  • 일부 기능이나 라이브러리에 대한 추가 설정이 필요
  • 작은 프로젝트의 경우 오버엔지니어링이 될 수 있음
  • 초기 빌드 시간이 상대적으로 긺
대체 기술
  • Express.js: 가벼운 웹 프레임워크로, 유연하고 빠르지만 대규모 애플리케이션에는 적합하지 않을 수 있다.
  • Fastify: Express.js와 유사한 성능을 가진 웹 프레임워크로, 더 빠르고 안정적이며 확장성이 뛰어나다.
  • LoopBack: IBM에서 개발한 오픈 소스 프레임워크로, 마이크로서비스 아키텍처를 구축하는 데 특화되어 있다
  • Adonis.js: Node.js를 위한 전체 스택 웹 프레임워크로, 간결하고 직관적인 구조를 가지고 있다.


보다 자세한 내용은 Nest.js 공식 문서를 참고하자.

동작 방식(라이프 사이클)


NestJS는 다음과 같은 라이프 사이클을 가진다:

각 단계별 상세 설명


1. Client Side -> HTTP Request

2. 미들웨어 (Middleware)

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: NextFunction) {
    console.log(`Request to ${req.path}`);
    next(); // 다음 단계로 진행
  }
}

3. 가드 (Guards)

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const request = context.switchToHttp().getRequest();
    return this.validateRequest(request);
  }

  private validateRequest(request: any) {
    // 인증 로직 구현
    return true;
  }
}

4. 인터셉터 (Interceptors - Before)

@Injectable()
export class TransformInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    // 요청 처리 전
    console.log("Before...");

    return next.handle().pipe(
      map((data) => {
        // 응답 데이터 변환
        return { data, timestamp: new Date() };
      })
    );
  }
}

5. 파이프 (Pipes)

import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import { ValidationPipe } from "@nestjs/common";

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(
    new ValidationPipe({
      whitelist: true, // DTO에 정의되지 않은 속성 제거
      forbidNonWhitelisted: true, // DTO에 정의되지 않은 속성이 있으면 요청 거부
      transform: true, // 요청 데이터를 DTO 타입으로 자동 변환
    })
  );
  await app.listen(process.env.PORT ?? 8080);
}
bootstrap();

결론


NestJS는 대규모 애플리케이션 개발에 적합한 프레임워크로, TypeScript를 기반으로 하며 모듈화된 아키텍처와 의존성 주입 시스템을 제공한다. 또한 다양한 기능과 라이브러리 통합을 지원하며, 확장성과 유지보수성이 뛰어나다. 하지만 학습 곡선이 상대적으로 높고, 초기 설정 및 구성이 복잡할 수 있다. 따라서 대규모 프로젝트나 마이크로서비스 아키텍처를 구축하는 경우에 적합하며, 작은 규모의 프로젝트나 간단한 웹 애플리케이션에는 Express.js나 Fastify와 같은 가벼운 프레임워크를 고려할 수 있다.

NestJS