개발개발/NestJS

[NestJS] 1. NestJS가 함수를 실행하기까지

camezii 2022. 10. 21. 01:39

이전 글에서도 소개했듯, NestJS는 효율적이고, 확장성이 좋은 웹 프레임워크이다.

이 글에서는 NestJS의 새 프로젝트를 생성하고, NestJS의 Controller, Module, Decorator, 그리고 Service에 대해 정리해보려 한다.

 

🐯 새 프로젝트 생성하기

NestJS의 새 프로젝트를 생성하기에 앞서 우선 @nestjs/cli 패키지를 설치해줘야 한다.

npm i -g @nestjs/cli

그리고 새 프로젝트를 생성해준다.

nest new [project name]

 

이때..! nest 명령어로 프로젝트가 생성되지 않는 경우가 생길 수 있다.

~/.zshrc 파일에 nest에 대한 alias를 추가해줘야 하는데 nest 대신 npx @nestjs/cli를 사용해도 생성할 수 있다!

npx @nestjs/cli new [project name]

 

 

 

🐯 기본 파일 소개

실질적으로 코드짜는 데에 사용되는 소스파일 외 몇 가지 파일의 존재이유(?)는 다음과 같다.

.eslintrc.js: 개발자들이 특정한 규칙을 가지고 코드를 깔끔하게 짤 수 있도록 도와주는 라이브러리
.prettierrc: 형식을 준수하기 위한 파일 (큰따옴표와 작은따옴표의 남발 없이 하나로 통일)
nest-cli.json: 프로젝트 자체에 필요한 설정을 추가해주는 json 파일

 

 

🐯 Module → Controller → Service → Function 실행!

ㄴ 이것이 바로바로 이 게시글의 핵심이 될지도 모르는 부분...!

 

처음 프로젝트를 생성하면 src 폴더에 다음 다섯 가지 파일이 함께 생성된다.

  • main.ts 1️⃣
  • app.module.ts 2️⃣
  • app.service.ts 4️⃣
  • app.controller.ts 3️⃣
  • app.controller.spec.ts

각 파일 뒤의 숫자는 파일이 실행되는 순서와 같다.

마지막 app.controller.spec.ts는 테스트 파일이므로 위 네 가지 파일에 집중하면 된다!

 

NestJS에서 함수를 실행하기 위한 방법을 최대한 이해하기 쉽게 정리해보려 노력했다 🔽🔽

 

1. main.ts에서 모든 것이 시작된다!

 

//-- 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();

main.ts에 생성된 AppModuleRoot Module이라고도 볼 수 있는데, 이를 통해 app.module.ts 파일로 redirect한다.

또한 Module은 애플리케이션의 일부로, Controller와 Provider의 개념이 중요하다✨

이 둘은 Controller와 Service가 기능할 수 있도록 한다⬇️⬇️

 

 

2. @Module의 Controller와 Service

 

//-- app.module.ts --//

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에서 controller와 service를 정의한다.

@Module과 같이 앞에 @가 붙어있는 것Decorator라 하는데, 클래스에 함수 기능을 추가할 수 있도록 해줌으로써 함수의 기능을 확장시키는 역할을 하고, 그 뒤에 등장하는 함수나 클래스와 꼭 붙여서 작성해야 한다!

뒤에 Get Decorator가 등장하고, 작성 예정인 이 다음 글에서도 굉장히 여러 Decorator가 등장하니 NestJS를 공부할 거라면 잘 알아두면 좋을 것 같다 🙂

 

 

3. Controller를 거치고, Service를 거쳐 드디어 함수를 실행한다!

 

//-- 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();
  }
}

Controller페이지의 url을 가져와서 function을 실행시키는 역할로, NodeJS의 Express 같은 역할을 한다.

여기서 방금 언급했던 Get Decorator가 등장하는데, 쉽게 이해하자면 Express에서 정의하는 Get Router라 볼 수 있다. app.get("/")과 같이 라우팅해줬던 것이 NestJS에서는 @Get()으로써 구현되는 것이다.

이는 곧 Get Request의 의미로, 어떤 url을 통해 어떤 함수를 실행하는지 알 수 있게 해주고, 결론적으로 controller는 AppService의 함수를 호출다.

 

//-- app.service.ts --

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

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

이렇게 Service에 도달하여 get Hello() 함수를 호출할 수 있게 되는 것이다.

 

 

 

그럼 이제 여기서 드는 의문점..!

Controller의 function에서 바로 값을 리턴하면 되는데 왜 Service가 또 굳이 필요한가?

 

그 이유는 바로, ✨NestJS는 Controller와 비즈니스 로직을 구분짓고 싶어하기 때문✨이다.

Controller는 url을 가져와서 함수를 실행시키는 역할을 하고,

Service는 실제로 함수를 저장하고 있는 코드로 역할이 구분되어 있다.

 

최종적으로 지금까지 계속 반복해 언급했던 것과 같이 Controller가 Service의 함수를 가져와 실행시킨다고 생각하면 된다.


이 다음부터는 여러 Decorator와 함께 영화의 API server를 구축해볼 것이다.

그럼 오늘 정리는 여기까지❗️