Search

NestJS

NestJS의 주요 특징은 무엇인가요?

NestJS는 모듈화의존성 주입(DI)TypeScript 기반데코레이터 패턴을 핵심 특징으로 합니다.
예를 들어, 모듈 시스템(@Module)을 통해 기능별로 코드를 분리해 확장성을 높이고, DI를 활용해 서비스 간 결합도를 낮춘 유지보수성 높은 아키텍처를 구성할 수 있습니다. 또한 Express/Fastify를 추상화해 유연한 HTTP 계층을 제공하며, GraphQLWebSocket마이크로서비스 등 다양한 백엔드 요구사항을 지원합니다.

NestJS에서 의존성 주입(Dependency Injection)이 왜 중요한가요?

DI는 클래스 간 결합도를 낮추고 테스트 용이성을 높이는 핵심 메커니즘입니다.
예를 들어, UserService가 UserRepository에 의존할 때, NestJS의 @Injectable() 데코레이터와 @Inject()를 통해 자동으로 의존성을 주입받습니다. 이를 통해 Mock 객체를 쉽게 주입해 단위 테스트를 작성할 수 있고, 모듈 교체 시 코드 변경을 최소화할 수 있습니다.

NestJS 모듈 시스템의 장점은 무엇인가요?

모듈(@Module)은 **관심사 분리(SoC)**를 통해 복잡한 시스템을 관리하기 쉽게 합니다.
예를 들어, AuthModuleOrderModulePaymentModule로 분리해 개발하면, 팀원 간 협업이 용이하고, 기능별로 라이브러리화해 재사용할 수 있습니다. 특히 imports 배열을 통해 다른 모듈의 기능을 통합할 수 있어, 마이크로서비스 아키텍처 구현에 유리합니다.

NestJS가 Express.js와 다른 점은 무엇인가요?

Express.js는 유연하지만 구조화된 규칙이 부족해 대규모 프로젝트에서 스파게티 코드가 발생할 수 있습니다. 반면 NestJS는 **아키텍처 패턴(Controller-Service-Repository)**을 강제해 코드 일관성을 유지하고, TypeScript를 기본으로 지원해 컴파일 단계에서 타입 에러를 방지합니다. 예를 들어, 데코레이터(@Get()@Post())로 라우팅을 명시적으로 정의해 가독성을 높입니다.

NestJS에서 인터셉터(Interceptor)의 역할은 무엇인가요?

인터셉터는 요청/응답의 전역 처리를 담당합니다. 예를 들어, 성공 응답을 { data: ..., error: null } 형태로 표준화하거나, 로깅, 에러 변환, 실행 시간 측정 등의 작업을 수행할 수 있습니다. 실제 프로젝트에서 인터셉터를 활용해 모든 API 응답을 포맷팅하고, 민감한 데이터를 마스킹하는 로직을 구현한 경험이 있습니다.

가드(Guard)와 미들웨어(Middleware)의 차이점은?

가드: 라우트 핸들러 실행 전 권한을 검증합니다. (예: JWT 검증, 역할 기반 접근 제어)
미들웨어: 라우트 핸들러 실행 전/후 요청/응답을 변형합니다. (예: CORS, 헤더 설정)
NestJS에서는 가드를 @UseGuards() 데코레이터로 특정 컨트롤러나 메서드에 적용해
*세분화된 인가(Authorization)**를 구현할 수 있습니다.

NestJS에서 테스트를 어떻게 진행하나요?

NestJS는 Jest 기반의 테스트 유틸리티(Test.createTestingModule())를 제공합니다.
단위 테스트: 서비스 클래스를 Mocking 없이 테스트.
통합 테스트: 전체 모듈을 로드해 엔드투엔드 API 검증.
예를 들어, UserService의 createUser 메서드를 테스트할 때,
userRepository를 Mock으로 주입해 데이터베이스 의존성을 제거할 수 있습니다.

NestJS로 마이크로서비스를 구현하는 방법은?

@nestjs/microservices 패키지를 활용해 RedisKafka 등을 통신 계층으로 사용합니다.
예를 들어, 주문 서비스와 결제 서비스를 분리할 때, Message Pattern을 정의해 서비스 간 이벤트 기반 통신을 구현하고,
API 게이트웨이를 통해 클라이언트에 단일 진입점을 제공할 수 있습니다.

NestJS에서 환경 변수를 관리하는 방법은?

@nestjs/config 패키지를 사용해 **환경별 설정 파일(.env)**을 로드합니다.
예를 들어, ConfigModule.forRoot({ isGlobal: true })로 전역 모듈을 설정하고,
ConfigService를 주입해 get('DATABASE_URL')처럼 접근할 수 있습니다.
보안을 위해 aws-secret-manager와 연동해 민감한 정보를 관리한 경험이 있습니다.