NestJS 또는 줄여서 Nest는 Node.js의 유연함을 가지면서 프레임워크 내에 유용한 기술을 다수 구현해둔 프레임워크이다.
NestJS는 Node.js에 기반을 둔 웹 API 프레임워크로서 Express 또는 Fastify 프레임워크를 래핑(wrapping)하여 동작한다.
래핑(Wrapping)
랩(wrap)으로 감싸듯이 기존의 라이브러리 등을 조금 더 사용이 쉽고 수월하게 한번 더 만드는 것
기본적으로 NestJS는 Express를 사용한다.
Fastify는 밴치마크상으로 Express에 비해 약 2배 정도 빠르지만 Express가 가장 널리 사용되고 있고 Express 기반 미들웨어가 NestJS와 호환되기 때문이다.
미들웨어(Middleware)
서비스 및 기능을 애플리케이션에 제공하는 소프트웨어
Node.js는 쉽게 사용할 수 있고 확장성이 좋지만, 과도한 유연함으로 인해 결과물인 소프트웨어의 품질이 일정하지 않고 적절한 라이브러리를 찾기 위해 사용자가 많은 시간을 사용해야한다.
이를 보완하기 위해 NestJS는 데이터베이스, 객체 관계 매핑(object-reletional mapping, ORM), 설정(configuration), 유효성 검사 등 많은 기능을 기본 제공하면서도 필요한 라이브럴리르 쉽게 설치하여 확장할 수 있는 Node.js의 장점을 그대로 가지고 있다.
NestJS는 앵귤러(Angular)의 영향을 많이 받았다. 모듈/컴포넌트 기반으로 프로그램을 작성할 수 있어 재사용성을 높이고, 제어의 역전(inversion of control, IoC), 의존성 주입(dependency injection, DI), 관점 지향 프로그래밍(aspect-oriented programming, AOP) 같은 객체 지향 개녕을 도입하였다.
또한 타입스크립트(typescript)를 기본으로 사용하여 타입스크립트가 가진 타입 시스템의 장점을 누릴 수 있다.
웹 프레임워크가 갖추어야 할 필수 기능이라면 다음과 같은 것들이 있다.
NestJS는 이 중 대부분을 프레임워크에 내장하고 있고, 내장하지 않는 기능들은 쉽게 다른 모듈을 가져다 사용할 수 있다.
Express는 이미 많은 회사들이 선택하여 운용되고 있는 검증된 프레임워크이다. 그러나 NestJS 또한 Express를 기본으로 선택하고 그 위에 여러 기능을 미리 구현해놓은 것이다.
이 둘을 간단히 비교하면 다음과 같다.
구분 | Express | NestJS |
---|---|---|
유연함/확장성 | Express는 가볍게 테스트용 서버를 띄울 수 있다. 아이디어를 빠르게 검증하는 데 좋지만, 단순하고 자유도가 높은 만큼 맞는 라이브러리를 찾기 위해 시간을 들여야 한다. 보일러플레이트를 미리 얹어놓은 깃허브 저장소(repository)들이 있어 이를 활용하는 것도 좋은 선택일 것이다. | 미들웨어, IoC, CQRS 등 많은 기능을 프레임워크 자체에 포함한다. 사용자는 공식 문서를 통해 쉽게 따라할 수 있으며, 원하는 기능이 없다면 다른 라이브러리를 적용하여 사용하는 것도 가능하다. |
타입스트립트 지원 | 추가 설정을 통해 사용 가능하다. | 기본 설정이다. 바닐라 자바스크립트로도 작성이 가능하다. |
커뮤니티 | 가장 크다. | 증가하고 있다. |
State of JS 2021에 따르면 아직 사용 경험은 많지 않다.
Express가 상위에 있는 이유는 다른 프레임워크들이 Express 기반으로 만들어진 이유도 있다.
이어서 설문 조사 결과를 살펴볼 것인데, SvelteKit, Astro, Remix, Next.js, Nuxt, Gatsby는 엄밀히 말해 모두 프런트엔드의 영역에 가깝고 순수 백엔드 프레임워크라고는 할 수 없다. 그러나 프레임워크가 해결하고자 하는 목적에 맞게 도입해서 함께 사용하면 좋은 프레임워크들이다.
이를 이해하고 State of JS 2021를 기반으로 만족도와 인지도 등의 측면에서 살펴보자.
NestJS 사용자들의 만족도는 여러 프레임워크 중 중간 정도 순위로 85% 정도로 나왔다.
NestJS의 인지도는 69% 정도로 Express의 97%라는 수치에 비해서는 낮다.
따라서 인기 있는 Express를 사용하는 것이 좋아보이지만 상용 제품을 만들기까지 시간이 오래 걸릴 수 있다. Express를 사용하면 필요한 라이브러리들을 npm에서 찾고 검토하는 과정이 필요하기 때문이다.
반면에 NestJS는 백엔드 서버가 갖추어야할 많은 필수 기능을 프레임워크 내에 내장하고 있고, 필요한 기능을 추가 설치 및 적용하기 쉽다. 또한 IoC, DI를 채택하여 객체 지향 프로그래밍과 모듈화를 쉽게 할 수 있다.
Nestjs 깃허브에는 PR이 제출될 때마다 Express, Fastify와의 성능 벤치마크 결과가 공개된다.
이는 각 PR의 Checks 탭에서 확인할 수 있으며, 위의 벤치마크 결과는 2023년 1월 6일에 merge된 #10811 PR의 결과이다.
NestJS에서는 Express와 Fastify를 적용했을 경우를 각각 구분하고, Express/Fastify 자체 성능도 측정한다. 측정 결과를 보면, Express가 Fastify보다 느리고, NestJS에 각각을 적용하면 약간 더 성능이 떨어지는 것을 알 수 있다.
이는 NestJS가 기본 제동하는 프레임워크의 크기가 크기 때문이다. 그러나 순수 Express/Fastify로 서버를 개발하다 보면 필수로 요구하는 라이브러리들을 추가하기 때문에 결국 NestJS에서 제공하는 기능을 모두 구현하면 성능 차이는 크지 않을 것이다.
Express 깃허브를 보면 최근 4.18.2 버전을 업데이트했지만 그 전까지는 몇 년간 개발이 정체되어 있었따. 5.0을 준비하고 있기도 하고 매우 안정적인 프레임워크라서 문제없이 운용되고 있다는 증거로도 볼 수 있지만 최신 트렌드를 따라가지 못한다는 우려가 있다.
그러나 NestJS는 꾸준히 발전하고 있으며, 깃허브를 통해 커뮤니케이션도 활발히 하고 있다.
NestJS는 Node.js를 기반으로 한다. 따라서 먼저 Node.js를 먼저 다운로드 해야 한다.
안정적인 버전인 LTS를 선택하여 설치하는 것을 권장하며 Node.js 공식 사이트를 통해 설치할 수 있다.
Node.js를 설치하면 기본적으로 Node.js의 패키지 매니저인 npm이 함께 설치된다. npm을 통해 https://www.npmjs.com/에 등록된 라이브러리 및 프레임워크들을 쉽게 설치, 삭제할 수 있게 해준다.
NestJS를 사용하기 위해서 먼저 @nestjs/cli
를 설치해야한다.
$ npm i -g @nestjs/cli
i
명령어는 install
명령어의 약어이다. -g
옵션은 컴퓨터의 클로벌 환경에 설치하겠다는 것으로 모든 디렉토리에서 해당 패키지를 실행할 수 있다.
참고로 글로벌 환경에서 패키지가 설치되는 경로는 npm root -g
명령어로 확인할 수 있다.
이제 콘솔에 nest
, nest -h
또는 nest --help
라고 입력하면 @nest/cli
가 제공하는 기능의 목록을 볼 수 있다.
$ nest
다양한 기능이 있지만 우리는 NestJS 프로젝트를 생성할 것이기 때문에 아래 명령어를 통해 프로젝트를 생성할 것이다.
$ nest new <project-name>
project-name에 해당하는 부분에 자신이 원하는 프로젝트 명을 기입하여 생성할 수 있다.
설치 도중 패키지 매니저를 어느 것으로 정할 것인지 묻는 화면이 나오면 원하는 것으로 선택하면 된다. 가장 무난한 것으로는 npm이며, yarn과 npnpm 또한 npm*과 함께 많이 쓰이는 자바스크립트 라이브러리 패키지 매니저이다.
설치를 마치면 보일러플레이트(boilerplate) 코드가 생성되어 아래처럼 디렉토리 구조를 구성한다.
보일러플레이트(boilerplate) 코드
꼭 필요한 기본 기능을 미리 준비해놓은 코드
아래 명령어를 통해 실행할 수 있다.
$ npm run start:dev
운영이 아닌 개발 단계에서는
npm run start
가 아닌npm run start:dev
명령어를 이용한 것이 좋다.
package.json
를 보면start:dev
키에 해당하는 값은nest start --watch
로--watch
옵션은 소스 코드 변경을 감지하여 코드를 저장할 때마다 서버를 다시 구동하는 옵션이다.
포트는 기본적으로 3000번으로 설정되어 있는데, main.ts
파일을 보면 포트 설정 코드를 볼 수 있다.
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000); // 포트 설정 부분
}
bootstrap();
- 한용재, "NestJS로 배우는 백엔드 프로그래밍", 제이펍, 2022
- https://2021.stateofjs.com/en-US/libraries/back-end-frameworks/