[nest.js] [NestJS] NestJS 구조 이해를 위한 필수 개념 정리 - Node.js/TypeScript/Express 비교 포함

 

0. 시작하며

 

https://bradbeighton.medium.com/nestjs-the-pros-and-cons-aff714607b07

 

NestJS는 백엔드 프레임워크입니다. 하지만 이걸 배우기 위해서는 먼저 다음 세 가지를 이해해야 합니다.

  • Node.js: 왜 자바스크립트로 서버를 만들 수 있을까?
  • TypeScript: 자바스크립트보다 안정적인 이유는 뭘까?
  • Express: Nest의 기반이 되는 웹 프레임워크

이해한 뒤에야 Nest가 왜 등장했는지, 무엇이 좋은지 알 수 있습니다.

 

1) Node.js란?

Node.js는 자바스크립트를 브라우저가 아닌 서버 환경에서도 실행할 수 있도록 만든 런타임입니다. Chrome의 V8 자바스크립트 엔진을 기반으로 하며, 비동기 처리와 이벤트 기반 구조 덕분에 빠르고 가볍게 동작합니다. 이로 인해 자바스크립트만으로도 백엔드 서버를 개발할 수 있게 되었습니다.

특징

  • 브라우저 밖에서도 자바스크립트 실행 가능
  • 이벤트 기반, 비동기 처리 방식
  • 서버 개발에 적합한 경량 구조

요약: 자바스크립트로 서버를 만들 수 있게 해주는 플랫폼

 

2) TypeScript란?

TypeScript는 Microsoft에서 만든 자바스크립트의 상위 언어로, 자바스크립트에 정적 타입 기능을 추가한 언어입니다. 변수와 함수에 명확한 타입을 지정할 수 있어 코드의 안정성이 높아지고, 컴파일 시점에 오류를 미리 확인할 수 있습니다. NestJS는 이 TypeScript를 기본 언어로 채택하여 타입 기반 설계를 권장합니다.

특징

  • 자바스크립트에 타입 시스템 추가
  • 컴파일 타임 오류 탐지
  • 유지보수가 쉬운 구조 작성 가능

요약: 타입이 있는 자바스크립트 = 더 안정적인 개발

 

3) Express란?

Express는 Node.js 기반의 대표적인 웹 프레임워크입니다. 요청을 받고, 처리하고, 응답을 반환하는 구조를 단순하게 구현할 수 있어서 빠르게 웹 서버를 구축할 수 있습니다. 다만, 구조에 대한 강제성이 없기 때문에 소규모 프로젝트에는 유리하지만, 규모가 커질수록 관리가 어려워질 수 있습니다.

특징

  • 간결하고 직관적인 라우팅 처리
  • 설정이 자유롭고 유연한 구조
  • 다양한 미들웨어와 풍부한 생태계 보유

요약: 간단한 웹 서버를 빠르게 만들 수 있는 도구


1. NestJS란 무엇인가요?

NestJS는 Node.js 위에서 동작하는 TypeScript 기반 백엔드 프레임워크입니다.
Angular에서 영향을 받아 모듈화, 데코레이터 기반 구조, 의존성 주입(DI) 등 현대적인 아키텍처를 제공합니다.

JavaScript로 작성된 Express의 자유도 높은 구조와 달리, NestJS는 구조화된 코드를 쉽게 작성할 수 있도록 도와주기 때문에 중·대형 프로젝트에 적합합니다.

 


2. 왜 NestJS를 사용할까요?

장점 설명
구조적 설계 모듈 단위로 코드를 나누어 유지보수에 유리
TypeScript 기반 정적 타입으로 컴파일 타임에 오류 방지
강력한 DI 시스템 객체 간 의존성을 효율적으로 관리 가능
Express/Fastify 통합 가능 기존 Node 생태계 그대로 활용 가능
테스트 친화적 유닛/통합 테스트를 쉽게 작성 가능
확장성 높은 아키텍처 WebSocket, GraphQL, gRPC 등 다양한 기술과 통합 용이

3. 주요 구성 요소

3.1 Module

애플리케이션을 논리적으로 분리하는 단위입니다. 각 모듈은 컨트롤러, 서비스, 프로바이더를 포함할 수 있습니다. Nest앱은 최소 하나의 AppModule을 가져야합니다.

@Module({
  controllers: [UserController],
  providers: [UserService],
})
export class UserModule {}

 

3.2 Controller

클라이언트 요청을 처리하는 라우터 역할을 합니다. 사용자의 요청(GET, POST 등)을 받아 어떤 로직을 실행할지 결정하는 입구

 

@Controller('user')
export class UserController {
  constructor(private readonly userService: UserService) {}

  @Get()
  getAll() {
    return this.userService.findAll();
  }
}

 

경축! 아무것도 안하여 에스천사게임즈가 새로운 모습으로 재오픈 하였습니다.
어린이용이며, 설치가 필요없는 브라우저 게임입니다.
https://s1004games.com

3.3 Service

실제 비즈니스 로직을 구현하는 부분입니다.

@Injectable()
export class UserService {
  findAll() {
    return ['User1', 'User2'];
  }
}

 

3.4 Decorator

클래스나 메서드에 메타데이터를 부여합니다. NestJS의 핵심 문법 요소입니다. 자바의 어노테이션이랑 거의 같다고 볼 수 있

예시: @Controller, @Injectable, @Get, @Post, @Param, @Body 등

@Get(':id')
findOne(@Param('id') id: string) {
  return `User ${id}`;
}

 

3.5 Dependency Injection (DI)

NestJS의 핵심 철학 중 하나는 의존성 주입입니다. 서비스나 클래스 내에서 직접 객체를 생성하는 대신, Nest의 DI 컨테이너를 통해 필요한 객체를 주입받습니다. 이를 통해 테스트가 용이하고, 코드의 확장성과 유지보수성이 높아집니다.

@Injectable()
export class UserService {
  constructor(private readonly userRepository: UserRepository) {}
}

UserRepository를 직접 생성하지 않고, Nest가 알아서 주입해줍니다.

// 자바일 경우
@Service
public class UserService {
    private final UserRepository userRepository;

    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
}

3.6 Pipe

Pipe는 클라이언트로부터 받은 데이터를 검증하거나 변환할 때 사용됩니다. 예를 들어, string으로 들어온 값을 number로 바꾸거나, DTO의 유효성을 검사할 수 있습니다. class-validator와 함께 자주 사용되며, Nest에서 제공하는 ValidationPipe가 대표적입니다.

// 숫자 변환
@Get(':id')
getUser(@Param('id', ParseIntPipe) id: number) {
  return `User ID is ${id}`;
}
// Dto 유효성 검사
@Post()
create(@Body(new ValidationPipe()) dto: CreateUserDto) {
  return this.userService.create(dto);
}

 

# 파이프 동작 흐름

[요청]
  ↓
Middleware: 토큰 파싱 등
  ↓
Guard: 로그인 했는지? 권한 있나?
  ↓
Pipe: 요청값 검증/변환
  ↓
Controller
  ↓
Service
  ↓
(예외 발생 시 → Exception Filter가 응답 처리)

 

3.7 Guard

Guard는 요청을 처리하기 전에 인증이나 권한 확인을 담당합니다. 예를 들어, 로그인하지 않은 사용자의 요청을 차단하거나, 특정 권한이 있는 사용자만 요청을 허용할 수 있습니다. Nest는 Passport를 기반으로 한 다양한 Guard 전략도 제공합니다.

@UseGuards(AuthGuard('jwt'))
@Get('profile')
getProfile(@Request() req) {
  return req.user;
}

 

3.8 Interceptor

Interceptor는 요청/응답 흐름 사이에서 동작하며, 공통 응답 포맷 처리, 로깅, 캐싱, 실행 시간 측정 등 다양한 작업에 활용됩니다.

@Injectable()
export class LoggingInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    console.log('Before request...');
    return next.handle().pipe(
      tap(() => console.log('After response...')),
    );
  }
}

 

3.9 Exception Filter

NestJS는 기본적으로 예외를 처리하지만, 특정 예외 상황에 대해 커스텀 필터를 만들면 더 정교한 응답 처리가 가능합니다.
HTTP 상태 코드, 메시지 포맷, 로깅 등을 일관되게 처리할 수 있습니다.

@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const response = host.switchToHttp().getResponse();
    response.status(exception.getStatus()).json({
      message: exception.message,
    });
  }
}

 

3.10 Middleware

Middleware는 라우팅 전에 동작하며, 요청 객체를 조작하거나 공통 로직(예: 로깅, 토큰 유효성 확인)을 삽입할 때 사용합니다.
Express의 app.use()와 유사한 방식입니다.

export function logger(req: Request, res: Response, next: NextFunction) {
  console.log(`Request... ${req.method} ${req.url}`);
  next();
}

이를 AppModule 또는 특정 모듈에서 등록하여 사용할 수 있습니다.

 

????마지막 요약

구성 요소 설명 예시
Module 기능 단위로 묶는 기본 단위. 컨트롤러, 서비스 등을 포함 @Module({ controllers: [], providers: [] })
Controller HTTP 요청을 받아 라우팅 처리 @Controller('user'), @Get()
Service 비즈니스 로직 담당. Controller와 분리 @Injectable() 사용
Decorator 클래스/메서드에 메타데이터를 부여 @Get(), @Param(), @Body() 등
Dependency Injection (DI) 의존 객체를 직접 생성하지 않고 자동 주입 생성자에 의존성 선언만으로 주입됨
Pipe 요청 데이터의 검증 및 변환 ValidationPipe, ParseIntPipe 등
Guard 요청 차단 또는 허용 (인증/권한 검사) @UseGuards(AuthGuard('jwt'))
Interceptor 요청/응답을 가로채어 공통 처리 (로깅, 캐싱 등) NestInterceptor 구현
Exception Filter 예외 발생 시 커스텀 응답 처리 @Catch(HttpException)
Middleware 요청 전 처리 로직 (로그, 인증 등) Express 스타일 req, res, next 사용

4. NestJS 시작하기

해당 관련한 글은 이미 이전에 작성한 포스트에 정리해 두었으니 설치를 하실 분은 아래 포스트로 접속해주세요!

5. 기본 프로젝트 구조 설명

src/
 ┣ app.controller.ts   # 요청 처리 라우터
 ┣ app.service.ts      # 비즈니스 로직
 ┣ app.module.ts       # 루트 모듈
 ┗ main.ts             # 앱 시작점

NestJS는 이러한 구조를 기본으로 제공하며, 기능이 늘어날수록 모듈 단위로 분리하여 확장할 수 있습니다.


6. Express와의 비교

항목 NestJS Express
언어 TypeScript JavaScript
구조 모듈 기반 자유로운 구조
테스트 지원 기본 제공 수동 설정 필요
학습 난이도 중간 낮음
확장성 높음 제한적

 

???? 핵심 차이 요약

  • NestJS는 Express보다 더 구조적인 개발을 유도합니다.
    Express는 유연하지만, 규모가 커질수록 유지보수가 어려워집니다. 반면 Nest는 모듈화, DI, 테스트 코드, 데코레이터 기반 설계 등으로 대규모 프로젝트에 최적화되어 있습니다.
  • NestJS는 선택이 아닌 '설계 강제력'을 제공합니다.
    Express에서는 아키텍처를 직접 설계해야 하지만, Nest는 프레임워크 차원에서 표준적인 구조를 강제하기 때문에 팀 단위 개발에 유리합니다.
  • NestJS는 테스트와 확장을 위한 기반이 이미 갖춰져 있습니다.
    예를 들어, Swagger 문서화, TypeORM/Prisma 연동, JWT 인증, WebSocket 사용 등을 위한 패키지가 공식적으로 지원됩니다. Express에서는 대부분 별도 설정이 필요합니다.

 

???? 언제 Express가 더 나을까?

  • 매우 간단한 REST API
  • 빠르게 프로토타입을 만들고 싶을 때
  • 구조 설계보다 빠른 결과물이 필요한 상황

???? 언제 NestJS가 더 유리할까?

  • 팀 프로젝트 또는 규모가 큰 백엔드 시스템
  • 여러 모듈/기능이 복잡하게 얽힌 경우
  • 테스트, 보안, 확장성까지 고려하는 환경
  • Angular 또는 Spring 개발자에게 친숙한 구조

7. 자바와의 비교

NestJS Java 설명
@Controller() @RestController HTTP 요청을 처리하는 클래스
@Get(), @Post() @GetMapping, @PostMapping 라우팅 메서드
Pipe + DTO + ValidationPipe @Valid + @RequestBody + Validator 요청 유효성 검사
Exception Filter @ControllerAdvice + @ExceptionHandler 예외 처리 핸들러
Middleware Filter, Interceptor 요청 전 공통 처리
Guard Spring Security Filter, @PreAuthorize 인증/인가 처리
Interceptor HandlerInterceptor 요청 전/후 가로채기
@Injectable() @Service, @Component DI 대상 등록용 클래스
DI (의존성 주입) @Autowired, 생성자 주입 객체를 직접 생성하지 않고 주입

 


✨ 마무리하며

NestJS는 단순히 Express 위에 만들어진 프레임워크가 아니라, 대규모 백엔드 개발에 필요한 아키텍처와 철학이 담긴 프레임워크입니다. 초기에는 익숙하지 않을 수 있지만, 구조에 익숙해질수록 유지보수성과 생산성에서 큰 장점을 느낄 수 있습니다. 이 포스트를 통해 NestJS의 기반 개념부터 Express와의 차이까지 이해하고, 자신의 프로젝트에 어떤 프레임워크가 적합할지 판단하는 데 도움이 되었기를 바랍니다.

 

 

출처: https://devjapan.tistory.com/17 [도쿄사는 신입 개발자:티스토리]

 

 

 

 

본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
번호 제목 글쓴이 날짜 조회 수
583 [javascript] React - Apache에 배포하기 file 졸리운_곰 2026.01.25 444
» [nest.js] [NestJS] NestJS 구조 이해를 위한 필수 개념 정리 - Node.js/TypeScript/Express 비교 포함 file 졸리운_곰 2025.12.12 501
581 [프론트앤드] 리액트(React) 간단 문법 정리 file 졸리운_곰 2025.11.19 549
580 [web design][웹디자인][알아봅시다] 왕초보 피그마 기초 사용법???? 셀러님들 지금 당장 피그마 시작하세요! 그대로 따라만 해서 피그마 정복하기 졸리운_곰 2025.07.21 246
579 [Next.js 개발] pm2 로 Next.js 실행하기 졸리운_곰 2025.07.01 480
578 [HTML] [HTTP] 주요 메서드 5가지 정리(GET / POST / PUT / PATCH / DELETE) file 졸리운_곰 2025.04.21 388
577 [JavaScript] Algorithm | Fizz Buzz 졸리운_곰 2025.01.03 365
576 [wordpress, 워드프레스] 워드프레스로 쉽게 랜딩 페이지 만들기 (feat. 엘리멘터, GeneratePress, Divi) file 졸리운_곰 2024.12.20 545
575 [wordpress, 워드프레스] WordPress 페이지또는 글에 별도 CSS와 JavaScript 추가하기 file 졸리운_곰 2024.12.19 353
574 [wordpress 플러그인] 코스모스팜. 회원관리 1.메뉴에 로그인 넣기 file 졸리운_곰 2024.08.25 513
573 [wordpress 플러그인] WP-Members로 회원제 사이트 만들기 file 졸리운_곰 2024.08.25 749
572 [HTML] How to force link from iframe to be opened in the parent window : iframe에서 부모 창에서 열리도록 링크를 강제하는 방법 졸리운_곰 2024.08.22 349
571 [LAMPP] Ubuntu 20.04에서 PHP 8.1을 설치하거나 업그레이드하는 방법 졸리운_곰 2024.08.18 329
570 [Javascript] jQuery 달력 위젯 datepicker 사용하기 file 졸리운_곰 2024.08.13 546
569 [Javascript] onload, ready file 졸리운_곰 2024.08.13 454
568 [javascript] 제이쿼리로 시도, 시군구 선택하기 졸리운_곰 2024.08.13 516
567 [HTML] CSS 파일 불러오기 졸리운_곰 2024.08.09 469
566 [HTML/CSS] [SCSS] HTML에 SCSS 적용하는 법 / how to apply scss to html file 졸리운_곰 2024.08.09 383
565 [HTML/CSS] [SCSS] HTML에 SCSS 적용하는 법 file 졸리운_곰 2024.08.09 610
564 [php worldpress] 워드프레스 새 서버 이전시 페이지 안나오는 문제 : How to Rewrite URLs with mod_rewrite for Apache on Ubuntu 20.04 file 졸리운_곰 2024.08.07 774
대표 김성준 주소 : 경기 용인 분당수지 U타워 등록번호 : 142-07-27414
통신판매업 신고 : 제2012-용인수지-0185호 출판업 신고 : 수지구청 제 123호 개인정보보호최고책임자 : 김성준 sjkim70@stechstar.com
대표전화 : 010-4589-2193 [fax] 02-6280-1294 COPYRIGHT(C) stechstar.com ALL RIGHTS RESERVED