내배캠 89일차

·2023년 2월 10일
0

내일배움캠프

목록 보기
97/142
post-thumbnail

NestJS 설치

  1. npm i -g @nestjs/cli
    어느 경로에서나 nest 커맨드를 사용할 수 있게 global 옵션으로 설치

  2. nest -v
    버전확인

  3. nest
    nest 커맨드에 대한 매뉴얼

  4. nest new [프로젝트명]
    새로운 Nest.js 프로젝트생성
    package manager는 가장 호환이 잘 되는 npm선택!

  • Nest.js 프로젝트 생성 실패 시
// 프로젝트 생성
git clone https://github.com/nestjs/typescript-starter.git [프로젝트명]

// 경로설정
cd [프로젝트명]

// 모듈설치
npm i

코드분석

main.ts

main.ts 파일은 절대로 임의로 파일 이름을 변경하면 안됨!
Nest.js에서 진입점으로 사용하겠다고 사전에 약속된 파일이기 때문.

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();

AppModule이라는 모듈을 루트 모듈로 사용하는 Nest.js 어플리케이션 인스턴스를 생성해줘!

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 {}

main.ts에서 루트 모듈로 지정이 된 AppModule!
Nest.js에서 모듈은 레이어드 아키텍처 패턴을 구성하는 컴포넌트들을 매니징한다고 보면 됩니다.

@Module

이게 뭘까요? 이렇게 @가 붙는 키워드를 데코레이터라고 합니다. 데코레이터란 해당 클래스나 함수가 어떤 역할을 수행하는지에 대해 Nest.js에 알려주는 역할을 합니다. 다시 말해서, 여기서는 AppModule이라는 클래스는 Nest.js 웹 어플리케이션 세계관에서 모듈이라는 역할을 할 거야~라고 선언을 한 것입니다.

미리 정의된 데코레이터는 각각 필요한 속성들이 다릅니다! 여기서는 @Module이라는 데코레이터는 imports, conrtollers, providers, 그리고 위의 코드에는 없지만 exports라는 속성을 가질 수 있습니다. 이외에도 더 많은 정의된 데코레이터들이 Nest.js에 준비되어 있음!

또한, 데코레이터는 단독으로는 사용할 수 없고 데코레이터를 꾸며주는 클래스나 함수와 반드시 같이 사용해야 한다는 점도 잊지 마세요!

@Module의 속성들

  • imports
    • 해당 모듈에서 필요한 모듈의 집합을 정의합니다.
    • 여기에 들어가는 모듈은 프로바이더(서비스)를 노출하는 모듈입니다.
    • 가장 흔하게 임포트를 하는 모듈 중 하나는 HttpModule(API 호출 모듈)이 있습니다.
    • 또한, 나중에 배우게 되는 TypeOrmModule을 이용하여 참조할 리포지토리를 가져오기도 합니다.
  • controllers
    • 해당 모듈에서 사용하는 컨트롤러를 정의합니다.
  • providers
    • 해당 모듈에서 사용하는 서비스를 정의합니다.
  • exports
    • 해당 모듈에서 노출시킬 서비스를 정의합니다.
    • 다른 모듈에서 해당 모듈의 서비스를 사용하기 위해서는 exports로 노출을 해야 사용할 수 있습니다.

app.controller.ts

모듈과 마찬가지로 @Controller 라는 데코레이터를 통해 AppController 클래스가 컨트롤러 역할을 하는 것을 Nest.js에 전달

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

DI & IoC

컨트롤러는 서비스를 반드시 의존해야 하며 이는 생성자를 통한 DI로 해결해야 합니다!

위의 생성자에서 인자로 AppService 객체를 넘기면 this.appService라는 멤버 변수에 AppService 객체가 주입되는 것을 볼 수 있습니다. 이것을 DI(의존성 주입)이라고 하며 이렇게 생성자를 통한 DI를 Nest.js에서 지원합니다. 어떻게 지원하는지를 묘사하면 대략 다음과 같습니다.

  • Nest.js의 IoC 컨테이너라는 친구는 @Injectable 혹은 @InjectRepository 와 같은 데코레이터가 달린 클래스를 트래킹하여 실제로 Nest.js 웹 어플리케이션이 실행될 때 동적으로 DI를 합니다!

@Get이라는 새로운 데코레이터가 보입니다. 이 @Get이라는 데코레이터는 HTTP GET으로 요청이 들어올 시 아래의 함수(코드에서는 getHello 함수)를 실행하라는 얘기입니다! 그렇다면, 하나 궁금한 게 있죠? 여러분들이 생각하시는 그것… 맞습니다!

@Get 뿐 아니라 @Post, @Put, @Delete 데코레이터도 이미 준비되어 있으니 단지 저희는 편하게 사용을 하면 됩니다. 이런 데코레이터들이 있어서 컨트롤러내에 각 함수는 어떤 요청을 담당하는지에 대해 매우 쉽게 파악할 수 있습니다!

app.service.ts

서비스는 리포지토리를 반드시 의존해야 하며 이는 생성자를 통한 DI로 해결해야 합니다!
단, 데이터베이스를 사용하는 경우에만 해당이 됩니다.

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

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

@Injectable 데코레이터

AppService가 나를 필요로하면 언제든지 DI를 통해서 나를 써봐~ 라고 얘기하는 것입니다! 그래서, 위에서 나온 AppController가 AppService를 잘 의존하고 있음.

app.controller.spec.ts

Jest라는 테스트 프레임워크를 통해서 테스트하는 코드

import { Test, TestingModule } from '@nestjs/testing';
import { AppController } from './app.controller';
import { AppService } from './app.service';

describe('AppController', () => {
  let app: TestingModule;

  beforeAll(async () => {
    app = await Test.createTestingModule({
      controllers: [AppController],
      providers: [AppService],
    }).compile();
  });

  describe('getHello', () => {
    it('should return "Hello World!"', () => {
      const appController = app.get(AppController);
      expect(appController.getHello()).toBe('Hello World!');
    });
  });
});
profile
개발자 꿈나무

0개의 댓글