첫 단계

CRUD 기능이 있는 어플리케이션을 같이 만들어보면서 Nest의 핵심 개념에 대해 이해하도록 하겠습니다.

언어

Nest는 타입스크립트를 우선적으로 지원하지만 순수 자바스크립트를 사용할 수 있습니다. Nest는 최신 언어 기능을 활용하므로 바닐라 자바스크립트 와 함께 사용하려면 Babel 컴파일러가 필요합니다.

공식 문서에서는 대부분 Typescript로 예제가 작성되어 있지만, 바닐라 자바스크립트 코드도 같이 제공하고 있습니다. (각 코드 스니펫의 오른쪽 상단에 있는 언어 버튼을 클릭). 하지만 저는 지금 글을 쓰는 도구의 한계로 Typescript로만 예제를 지원하도록 하겠습니다.

필요사항

  • Node.js (> = 10.13.0, v13 제외)

설치

맨 첫 장에서 설명한대로 스켈레톤 프로젝트를 만드는 방법에는 3가지가 있는데, 그 중 가장 쉽고 널리 쓰이는 Nest CLI로 프로젝트를 만들어 보겠습니다. Nest CLI를 설치하고 새로운 프로젝트를 만든다는 명령어를 입력하면 됩니다.

$ npm i -g @nestjs/cli
$ nest new project-name

패키지 매니저를 npm으로 사용할건지 yarn으로 사용할건지 물어보고, 몇 가지 파일을 생성하고 필요한 노드 모듈을 설치합니다. 만들어진 프로젝트 루트로 가보겠습니다. 아래는 맥에서 ls로 파일 내역을 확인한 화면입니다.

-rw-r--r--    1   staff   3.3K  5  8 10:36 README.md
-rw-r--r--    1   staff    64B  5  8 10:36 nest-cli.json
drwxr-xr-x  605   staff    19K  5  8 10:37 node_modules
-rw-r--r--    1   staff   710K  5  8 10:37 package-lock.json
-rw-r--r--    1   staff   1.9K  5  8 10:36 package.json
drwxr-xr-x    7   staff   224B  5  8 10:36 src
drwxr-xr-x    4   staff   128B  5  8 10:36 test
-rw-r--r--    1   staff    97B  5  8 10:36 tsconfig.build.json
-rw-r--r--    1   staff   339B  5  8 10:36 tsconfig.json

생성된 디렉토리와 파일에 대해서 설명해보겠습니다.

이름설명
README.mdREADME 파일
node_modules앱에 필요한 라이브러리 설치 디렉토리
package-lock.json설명 생략
package.json설명 생략
src소스파일
testE2E(End-to-End Testing) 디렉토리
tsconfig.build.json빌드할때 필요한 타입스크립트 설정
tsconfig.json타입스크립트 설정

중요한건 src 디렉토리입니다. src 디렉토리를 살펴보겠습니다.

이름설명
app.controller.ts하나의 경로(route)만 있는 컨트롤러
app.controller.spec.ts컨트롤러 단위 테스트
app.module.ts어플리케이션 루트 모듈
app.service.ts하나의 메소드만 있는 서비스
main.tsNestFactory를 사용해서 Nest 어플리케이션 인스턴스를 생성하는 어플리케이션의 시작점

여기에 모르는 단어가 많이 나옵니다. 컨트롤러, 서비스, 모듈 입니다. 이건 천천히 알아가도록 하겠습니다.

그럼 이 어플리케이션의 시작점인 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();

코드는 굉장히 간단합니다. bootstrap이라는 함수를 정의하고 이를 실행하고 끝납니다. 상식으로 bootstrap이라는 단어는 컴퓨터 분야에서 보통 한 번 시작하면 다른 외부의 도움없이 스스로 진행하는 행위를 말합니다. 상세한 설명은 여기를 참고하세요. 다시 코드로 돌아와서 이 함수 내에서는 NestFactory를 사용하여 어플리케이션 인스턴스를 생성합니다. NestFactory는 Nest 응용 프로그램을 만들수 있는 몇 가지 정적 메소드를 제공하는데, create()메소드는 INestApplication 인터페이스를 충족하는 응용 프로그램 객체를 반환합니다. 이 객체는 위 코드처럼 3000번 포트를 열고 인바운드 HTTP 요청을 기다리며, 요청이 오면 이를 처리하고 응답을 보내는 웹서버의 역할을 합니다.

플랫폼

Nest는 플랫폼에 구애받지 않은 프레임워크를 목표로 합니다. 플랫폼을 독립적으로 만들었기 때문에 이를 통해 개발자가 여러 유형의 응용 프로그램에서 활용할 수 있는 재사용 가능한 논리적 부분을 만들 수 있습니다. 기술적으로 Nest는 어댑터가 생성되면 모든 Node HTTP 프레임워크와 함께 사용할 수 있습니다. Node 기반 HTTP 프레임워크는 크게 Express, Koa, Fastify가 있지만 Nest는 기본적으로 Express와 Fastify를 지원합니다. 이 중 적절한 걸 선택하면 됩니다.

platform-express

두 말할 나위없는 가장 유명한 Node기반 웹 프레임워크입니다. 많은 사용자가 있으며, 수 많은 프로덕션에서 그 성능과 안정성을 검증받은 프레임워크입니다. Nest에서는 기본으로 Express를 사용하기 때문에 추가 설정이 필요없습니다.

platform-fastify

속도와 효율성을 중시하는 웹 프레임워크입니다. Express대비 거의 2배의 속도와 처리량, 그리고 짧은 지연속도(Latency)를 자랑합니다.

express, fastify 중 어떤 플랫폼을 선택해도 그 플랫폼 API가 아닌 Nest에서 정의한 어플리케이션 인터페이스를 노출합니다. Express는 NestExpressApplication가 되며, Fastify는 NestFastifyApplication이 됩니다.

전전 단락에서 "INestApplication 인터페이스를 충족하는 응용 프로그램 객체"가 바로 NestExpressApplicationNestFastifyApplication입니다. 이 두 개 모두 INestApplication을 상속하기 때문입니다. 아래는 실제 정의한 코드입니다.

export interface NestExpressApplication extends INestApplication {
  // ...
}
export interface NestFastifyApplication extends INestApplication {
  // ...
}

NestFactory.create()에 아래와 같이 메소드에 유형을 전달 하면 app객체는 해당 특정 플랫폼에서만 사용할 수 있는 메소드를 갖게됩니다.

const app = await NestFactory.create<NestExpressApplication>(AppModule);

그러나 실제로 기본 플랫폼 API를 사용하려는 경우가 아니면 굳이 유형을 지정할 필요가 없습니다. X랄같은 버그를 만나지 않는다면 Nest에서 제공하는 API 쓰기도 바쁩니다.

응용 프로그램 실행

Nest CLI로 설치가 완료되면 OS 명령 프롬프트에서 다음 명령을 실행하여 인바운드 HTTP 요청을 수신하는 애플리케이션을 시작할 수 있습니다.

$ npm run start

이 명령은 src/main.ts 파일에 정의된 포트에서 수신 대기하는 HTTP 서버로 앱을 시작 합니다. 기본은 3000번 포트로, 애플리케이션이 실행되면 브라우저 주소창에 http://localhost:3000/ 를 입력해봅시다. Hello World! 메시지가 표시되면 잘 동작하고 있는겁니다.