[NestJS] 1. NestJS가 함수를 실행하기까지
이전 글에서도 소개했듯, 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에 생성된 AppModule은 Root 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를 구축해볼 것이다.
그럼 오늘 정리는 여기까지❗️