Node.js로 백엔드를 개발할 때 코드가 점점 커지면 구조가 흐트러지기 쉽다. NestJS는 이 문제를 Angular에서 영감을 받은 모듈 시스템과 데코레이터 기반 아키텍처로 해결한다. TypeScript를 기본으로 채택해 타입 안전성과 IDE 지원을 동시에 얻을 수 있다.
NestJS는 Node.js 위에서 동작하는 서버 사이드 애플리케이션 프레임워크다. 내부적으로는 Express (또는 선택적으로 Fastify)를 HTTP 레이어로 사용하지만, 그 위에 모듈·컨트롤러·서비스라는 명확한 레이어 구조를 강제한다.
데코레이터(Decorator): @Controller, @Injectable 같이 클래스나 메서드에 메타데이터를 붙이는 TypeScript 문법.
| 항목 | Express | NestJS |
|---|---|---|
| 구조 | 자유로운 파일 배치 | 모듈 단위 강제 구조 |
| TypeScript | 선택 | 기본 |
| DI 컨테이너 | 없음 | 내장 |
| 학습 곡선 | 낮음 | 중간 |
| 대규모 팀 적합성 | 낮음 | 높음 |
Express는 최소한의 규칙만 제공해 빠르게 시작하기 좋지만, 팀이 커질수록 코드 컨벤션을 별도로 관리해야 한다. NestJS는 처음부터 규칙을 내장해 팀원 간 코드 스타일이 일관된다.
Client
│
▼
[ Controller ] ← 요청 수신, 라우팅
│
▼
[ Service ] ← 비즈니스 로직
│
▼
[ Repository ] ← DB 접근 (TypeORM, Prisma 등)
│
▼
Database
Module이 Controller와 Service를 묶는 단위다. 기능별로 UserModule, AuthModule 등으로 분리해 의존성을 명확히 관리한다.
DI(Dependency Injection): 객체가 필요한 의존성을 직접 생성하지 않고 외부에서 주입받는 패턴. NestJS는 이를 자동으로 처리한다.
소규모 프로토타입이나 스크립트성 서버라면 Express나 Fastify 단독이 더 가볍다.
npm i -g @nestjs/cli
nest new my-project
cd my-project
npm run start:dev
CLI가 기본 모듈 구조를 자동 생성해준다. 이후 새 리소스는 nest generate resource user 한 줄로 Controller·Service·Module을 한 번에 만들 수 있다.
import { Controller, Get, Param } from '@nestjs/common';
import { UserService } from './user.service';
@Controller('users')
export class UserController {
constructor(private readonly userService: UserService) {}
@Get(':id')
findOne(@Param('id') id: string) {
return this.userService.findOne(+id);
}
}
@Controller와 @Get 데코레이터가 라우팅을 선언하고, 생성자 주입으로 UserService를 받는다. 별도의 라우터 등록 코드 없이 데코레이터만으로 구조가 완성된다.
장점
단점