남느 2025. 4. 14. 16:12

NestJS는 Node.js 환경에서 서버 애플리케이션을 구축하기 위한 백엔드 프레임워크다.

NestJS가 필요한 이유

Node.js를 사용한 백엔드 개발 시 가장 많이 사용하는 프레임워크는 Express다.
Express는 미들웨어를 연결해주는 역할만 하기 때문에 생기는 문제가 있는데 NestJS는 이 문제들을 해결해준다.

구조 문제 해결

Node.js 환경의 백엔드 프레임워크들은 파일/폴더 구성을 강제 하지 않는다. 이로 인해 Node.js로 작성된 백엔드 프로젝트들은 개발자마다 파일/폴더 구성이 제각각이라 동일한 프로젝트 안에서도 코드 파악이 어려운 문제가 발생한다.
NestJS는 일정한 파일/폴더 구성을 강제해 구조 문제를 해결한다.

초기 설정 문제 해결

Node.js 환경에서 백엔드 애플리케이션을 구축할 때 가장 많이 사용하는 Express(Express 뿐만 아니라 대부분의 프레임워크들도)는 애플리케이션 구축을 할 때마다 로그, 보안, 인증 등 필요한 라이브러리들을 찾아서 설치하고 설정해야 한다.
NestJS는 이러한 기능들을 기본 제공한다.

NestJS의 특징

  • 모듈화: 애플리케이션을 모듈로 나누어 관리하고, 코드의 재사용성을 높인다.
  • 의존성 주입: 객체를 프로그래머가 아니라 프레임워크에서 관리하여, 코드의 결합도를 낮추고, 테스트 용이성을 높인다.
  • 데코레이터: 클래스와 메서드에 메타데이터를 추가하여 코드의 가독성을 높이고 기능을 확장한다.
  • 관점 지향 프로그래밍 : 로깅, 보안, 에러 처리 등 프로그램 전체에서 필요한 부분을 NestJS가 처리하기 때문에 핵심 로직에만 집중할 수 있다.

모듈화

하나의 앱은 여러 기능들이 있는데, 여러 기능들을 모듈로 나누어 관리하면 재사용성이 높아지고, 유지보수에 용이하다.

의존성 주입

의존성 주입(Dependency Injection)은 제어의 역전을 구현하는 방법의 하나로, 객체의 생성 및 관리를 개발자가 아니라 프레임워크에서 하는 것을 의미한다.

제어의 역전

제어의 역전(IoC; Inversion of Control)은 프로그램의 로직을 개발자가 아니라 라이브러리 혹은 프레임워크에서 제어하도록 위임하는 디자인 패턴을 말한다.

 

제어의 역전을 적용하지 않은 코드

main(){
 if(A일 때)
 else(B일 때)
}

제어의 역전을 적용한 코드

main(){
 위임함수()
}

위임함수(){
 if(A일 때) return A의 결과
 else(B일 때) return B의 결과
}

의존성 주입 예시

의존성 주입을 적용하지 않은 코드

class AppController {
  moduleA;
  constructor(){
    this.moduleA = new ModuleA();
  }
}

의존성 주입을 적용한 코드

class AppController {
  private moduleA: ModuleA
}

// 프레임워크에서 관리하기 때문에 아래 코드는 신경쓰지 않아도 된다.
class NestFactory() {
  create(){ /* 인스턴스 생성 및 관리를 대신해주는 코드 */ }
}

의존성 주입의 이점

  • 결합도 감소: 객체 간 결합도를 낮추어 유지보수성을 높인다. (결합도가 0이 되는 것이 아니라 줄어드는 것이다)
  • 테스트 용이성 : 애플리케이션 전체에서 동일한 객체를 사용하기 때문에 테스트가 용이하다.

데코레이터

데코레이터를 사용해 클래스, 메서드가 어떤 역할을 하는지 명확히 하면서, 기능을 추가할 수 있다.

데코레이터를 사용하지 않은 코드 (Express)

const router = express.Router();

router.get('/post/:id', (req, res) => {
  if (typeof (req.id) !== 'string') String(req.id)
  res.send(`post ${id}`);
});

데코레이터를 사용한 코드 (NestJS)

@Controller('post')
class PostController {
  @Get(':id')
  getPostId(@Param('id', ParseStringPipe) id: string){
    return `post ${id}`;
  }
}

관점 지향 프로그래밍(AOP; Aspect-Oriented Programming)

Express를 사용하면 라우팅마다 로직이 다를 경우 직접 연결하고 처리해야한다.

NestJS는 라우팅마다 로직이 다른 경우 데코레이터를 이용해 연결하여 처리할 수 있기 때문에 핵심 로직에 집중하기 쉽다.