본문 바로가기

Backend/NestJS

NestJS의 main.ts를 파헤쳐보자

nest new를 터미널에 입력하면 새로운 nest 프로젝트가 생성된다. 

이것을 VSCode에서 열고 실행을 해보면 NestJS에 깔린 기본 내장 프로젝트들이 미리 설치되어 있다. 

 

그중에서도 main.ts를 눈여겨보자. 

Nest에서는 NestFactory라는 기능을 사용하여 nest 애플리케이션 인스턴스를 생성하는 애플리케이션의 엔트리 파일이다. 

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()->(아무 이름이나 상관없음)이라는 기존 내장 함수를 통해 NestFactory가 nest 애플리케이션의 인스턴스를 생성할 수 있는 것이다. 

포트는 3000번을 사용한다. 

localhost:3000을 실행해보면 Hello World!가 출력된다. 

 

* if, await app.listen(3001)로 한다면 어떤 결과가 출력될까? 

// 20230823202614
// http://localhost:3000/

{
  "timestamp": "2023-08-23T11:26:14.799Z",
  "statusCode": 200,
  "result": "Hello World!"
}

 

statusCode가 200이기 때문에 요청은 정상적으로 들어갔고, results는 Hello World!라고 한다.

그런데 이 Hello World!라는 result는 어디서 오는 것일까? 

 

위의 bootstrap() 함수를 파헤쳐보자. 

NestFactory를 통해 AppModule을 create하여 app을 생성하는데, AppModule은 무엇일까? 

 

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

@Module()이라는 데커레이터가 나온다. 여기서는 모듈들을 관리하는 app.module.ts 파일로 연결이 된다. 

Nest에서 흔히 사용하는 controller, providers(Service), imports 등을 디렉토리마다 관리한다. 

 

AppController는 어떻게 생겼을까? 

 

app.controller.ts 

import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }
}

 

@Get() 데커레이터를 통해 AppController를 export 한 것을 확인할 수 있다. 위의 모듈 파일에서 나온 controllers: [AppController]에 등록된 것이다. NestJS는 이처럼 해당 디렉토리에서 사용할 controller와 service 파일에 대해 모듈 등록을 해주어야 한다. 

 

getHello()라는 함수는 string type의 값을 반환하는데, 위의 controller 파일에서는 어떤 값을 반환해주지는 명시되어 있지 않다. 

대신에 appService의 getHello(); 함수를 return할거다 라고 한 줄이 적혀있는데, appService로 이동을 해서 getHello() 함수를 보자. -> 위의 constructor 구조도 잘 보자.  appService 의존성이 주입되어 있다. 

 

app.service.ts

import { Injectable } from '@nestjs/common';

@Injectable()
export class AppService {
  getHello(): string {
    return 'Hello World!';
  }
}

AppService에 와보니 controller에서 명시되었던 getHello() 함수가 정의되어 있다. 이 또한 string값의 type을 반환하는데, 

여기서 Hello World!를 반환한다고 나와있다. 

그리고 service에서는 @Injectable() 키워드가 중요한데, 

 

결국 service > controller > main.ts 단을 통해 브라우저에서 Hello World!가 출력된 것을 볼 수 있었던 것이다.