코딩캠프/내일배움캠프

[ TIL ] 02.13(월) 64일차

고랑E 2023. 2. 13. 21:00
728x90

Nest.js 입문

 

코드분석 - main.js

 

main.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();

 

main.js 파일은 Nest.js 애플리케이션의 시작점(entry point)으로,

애플리케이션의 설정과 시작 프로세스를 정의,

Nest Factory를 사용하여 애플리케이션 인스턴스를 생성,

HTTP 서버를 시작.

 

const app = await NestFactory.create(AppModule);

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

레이어드 아키텍처 패턴 구성하는 컴포넌트들을 매니징한다.

 

@가 붙은 키워드를 데코레이더라고 함

@Module() 데코레이터는 Nest.js에서 모듈을 정의할 때 사용

@Module() 데코레이터에는 다양한 속성을 설정할 수 있다,

 

주요 @Module() 속성

  • imports: 현재 모듈이 사용할 다른 모듈들을 정의
    • 여기에 들어가는 모듈은 프로바이더(서비스)를 노출하는 모듈
    • 가장 흔하게 임포트를 하는 모듈 중 하나는 HttpModule(API 호출 모듈) 
    • TypeOrmModule을 이요하여 참조할 리포지토리를 가져오기도 함
  • controllers: 현재 모듈에서 사용할 컨트롤러들을 정의
  • providers: 현재 모듈에서 사용할 서비스들을 정의
  • exports: 현재 모듈에서 선언한 컴포넌트, 서비스, 모듈을 다른 모듈에서 사용할 수 있도록 공개함.

  • providers, controllers, exports 등에는 배열 형태로 값을 지정할 수 있다.
  • imports, providers, controllers, exports 등에는 다른 모듈 또는 클래스의 배열이나 프로바이더를 직접 선언할 수 있다.
  • dynamic: 런타임 시에 모듈이 동적으로 생성될 수 있도록 지정.
  • global: 현재 모듈의 프로바이더가 애플리케이션 전체에서 전역적으로 사용될 수 있도록 지정.

코드분석 - 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 라는 데코레이터를 통해 AppController 클래스가 컨트롤러 역할을 함

컨트롤러는 HTTP 요청을 처리하고,

해당 요청에 대한 응답을 반환하고.

이를 통해 클라이언트와 서버 간에 데이터를 주고받을 수 있다.

 

constructor(private readonly appService: AppService) {}

 

위의 생성자에서 인자로 AppService 객체를 넘기면 this.appService라는 멤버 변수에 AppService 객체가 주입되는 것을 볼 수 있습니다.

이것을 DI(의존성 주입)이라고 하며 이렇게 생성자를 통한 DI를 Nest.js에서 지원합니다.

어떻게 지원하는지를 묘사하면 대략 다음과 같습니다.

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

컨트롤러에서는 의존성 주입(Dependency Injection)을 이용해 서비스를 주입받을 수 있다.

이를 통해 컨트롤러와 서비스 사이의 결합도를 낮추고, 테스트와 유지보수를 용이하게 만들 수 있다.

컨트롤러에서 서비스를 주입받기 위해서는

@Controller() 데코레이터로 정의한 클래스 내에 생성자(constructor)를 정의하고,

해당 생성자 매개변수에 서비스 클래스를 주입받는 방식을 사용.

이를 통해 컨트롤러 클래스에서 서비스 클래스의 메서드를 호출하거나 속성에 접근한다.

 

@Get(), @Post(), @Put(), @Delete() 등의 데코레이터를 사용하여

각각 GET, POST, PUT, DELETE 요청을 처리할 수 있는 메서드를 정의한다.


코드분석 - app.service.ts

 

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

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

 

서비스는 일반적으로 데이터베이스와 같은 데이터 소스와의 상호작용을 처리하거나,

외부 서비스와의 통신을 처리하는 데 사용.

서비스는 컨트롤러와 같은 다른 클래스에서 사용될 수 있으며,

의존성 주입을 이용하여 주입됨.

 

💡 서비스는 리포지토리를 반드시 의존해야 하며 이는 생성자를 통한 DI로 해결해야 합니다!

단, 데이터베이스를 사용하는 경우에만 해당이 됩니다.


코드분석 - app.controller.spec.ts

 

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

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

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

    appController = app.get<AppController>(AppController);
  });

  describe('root', () => {
    it('should return "Hello World!"', () => {
      expect(appController.getHello()).toBe('Hello World!');
    });
  });
});

해당 코드는 AppController를 Jest라는 테스트 프레임워크를 통해서 테스트하는 코드입니다. 당연하지만, 여러분들이 새롭게 작성하신 컨트롤러 및 서비스들은 유닛 테스트 및 E2E 테스트를 통과해야 합니다

 

일반적으로 app.controller.spec.ts 파일에는 다음과 같은 내용이 포함됨

  1. 필요한 Nest.js 모듈과 테스트 도구를 임포트
  2. 테스트 케이스를 작성. 테스트 케이스는 주로 describe와 it 함수를 사용하여 작성. describe 함수는 테스트 스위트를 정의하며, it 함수는 개별 테스트 케이스를 정의
  3. 각 테스트 케이스에서는 HTTP 요청과 응답을 시뮬레이션하고, 컨트롤러의 동작을 검증.