Nest.js 의 기본 프로그램 구조

ayboori·2024년 11월 28일

Nest.js

목록 보기
5/11

Nest.js는 백엔드 서버를 구축하기 위한 Node.js 프레임 워크이다.
TypeScript를 지원하며, 순수 JavaScript로도 사용가능하다.

프로그램 구조

Module

  • CLI를 통한 생성 $ nest g module cats

특정 기능을 관리하는 모듈

CatsModule

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
	imports: [DogModule], // 다른 모듈에서 export 받을 목록
	controllers: [CatsController], // 이 모듈의 컨트롤러
	providers: [CatsService], // 이 모듈에서 공급 받아 사용
	exports: [CatsService] // 다른 모듈에 공급
})
export class CatsModule {} 
// 다른 모듈에서 사용할 수 있도록 export
// CatsModule을 import 하는 모듈들은 CatsService를 사용할 수 있다.
// imports한 모듈을 exports 할 수 있다

루트 모듈 - app.module.ts


import { Module } from '@nestjs/common';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule], // 사용할 모듈 지정
})
export class AppModule {}

종속성 주입


import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {
  constructor(private catsService: CatsService) {} // 공급자를 주입
  // 모듈 클래스 자체를 주입 받을 수는 없다.
}

@Global

모듈 선언 시 맨 위에 @Global() 선언

  • imports 선언 없이 모든 모듈에서 Global 모듈의 exports 사용 가능

동적 모듈

https://velog.io/@ayoung3052/Nest.JS%EC%9D%98-%EB%8F%99%EC%A0%81-%EB%AA%A8%EB%93%88

Controller

https://docs.nestjs.com/controllers

들어오는 요청을 처리하고, 클라이언트에게 응답을 반환한다.

import { Controller, Get } from '@nestjs/common';

@Controller('cats') // route prefix
export class CatsController {
  
  @Get()
  findAll(@Req() request: Request): string { // Reqeust 객체를 읽어온다.
    return 'This action returns all cats';
  }
}
  • Get / Post 등의 HTTP request Method Decorater을 사용한다.
    - 경로에 와일드카드를 사용할 수 있다.

반환 타입

  • JavaScript 개체나 배열은 반환하면 자동으로 JSON으로 직렬화된다.
    - string / number / boolean 등의 primitive Type의 경우 값만 보낸다.
  • library response Object 사용 시 특정 타입을 반환할 수 있다.
    findAll @Res() response
  • 상태 코드
    @HttpCode(204) / @HttpCode(HttpStatus.CREATED)
  • 헤더
    @Header('Cache-Control', 'no-store')
  • redirection
    @Redirect('https://nestjs.com', 301)

request Decorator 목록

매개변수가 있는 경로

@Get(':id') // 정적 경로 뒤에만 매개변수 경로를 사용할 수 있다.
findOne(@Param() params: any): string {
  console.log(params.id); // param으로 읽어온 값 중 경로의 id 값
  return `This action returns a #${params.id} cat`;
}


@Get(':id')
findOne(@Param('id') id: string): string { // param에서 변수 지정 시
  return `This action returns a #${id} cat`; // id 변수로 바로 사용 가능
}
  • @Param : @UUIDParam('id') id: number) 등으로 타입을 지정할 수 있다.

Service

  • CLI를 통한 생성 : $ nest g service cats

예제


import { Injectable } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';

@Injectable() // 클래스 생성, 주입이 가능한 상태로 만듦
// 이후 providers에 등록을 시켜 DI > 다른 곳에서 생성자로 주입하여 사용할 수 있다.
export class CatsService {
  private readonly cats: Cat[] = [];

  create(cat: Cat) {
    this.cats.push(cat);
  }

  findAll(): Cat[] {
    return this.cats;
  }
}

controller에서 사용

import { Controller, Get, Post, Body } from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';
import { CatsService } from './cats.service';
import { Cat } from './interfaces/cat.interface';

@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {} // Service 의존성 주입

  @Post()
  async create(@Body() createCatDto: CreateCatDto) {
    this.catsService.create(createCatDto);
  }

  @Get()
  async findAll(): Promise<Cat[]> {
    return this.catsService.findAll();
  }
}

@Injectable()

https://velog.io/@lionjy06/nestJs%EC%9D%98-injectable%EC%9D%B4%EB%9E%80

  • Spring의 @Component와의 공통점

  • 의존성 주입 설정
    DI 컨테이너에서 인스턴스화되며, 다른 클래스에서 주입될 수 있습니다.

  • 생성자 기반 주입
    필요한 의존성을 생성자 파라미터로 선언하면, DI 컨테이너가 자동으로 해당 의존성을 주입합니다.

  • 싱글톤 기본 전략
    각 클래스의 인스턴스를 싱글톤으로 관리

  • 차이점

  • NestJS는 데코레이터(Decorator)를 사용 / Spring은 Java의 애너테이션(Annotation)을 사용합니다.
    데코레이터는 함수처럼 실행되며, Spring의 애너테이션은 주석 형태로 동작합니다.

  • 모듈 시스템
    NestJS는 모듈 기반 아키텍처를 강제합니다.
    모든 서비스는 특정 모듈에 속해야 하며, 모듈에서 해당 서비스를 providers로 등록해야 합니다.

Spring에서는 이러한 명시적인 모듈 개념이 없으며, 패키지와 클래스 간의 구조로 의존성을 관리합니다.


DI 의존성 주입

Service: 제품
Provider: 공급자
controller 소비자

공급자가 제품을 제공해줘야 소비자가 사용할 수 있듯, Provider에 Service를 등록해주어야 Controller에서 주입받아 사용이 가능하다.

  1. Service 선언

  2. Module에 등록

import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';
import { CatsService } from './cats/cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService], // 공급자 정의
})
export class AppModule {}
  1. Controller에서 사용

싱글톤 인스턴스

  • NestJS는 싱글톤 패턴을 기본으로 사용한다.

  • 대부분의 서비스는 애플리케이션 전반에서 하나의 인스턴스만 공유한다.

  • 요청 간의 상태를 공유한다.
    - 단일 스레드 기반의 이벤트 루프 모델을 따른다

  • 데이터베이스 연결 풀 관리, 글로벌 상태 유치 측면에서 유리하다.

싱글톤이 아닌 요청 범위로 변경

필요 상황

  • 요청별 캐싱(Request-scoped caching)
    요청마다 다른 데이터를 유지해야 하는 경우.

  • 요청 추적(Request tracking)
    각 요청에 대해 고유한 정보를 저장하고 싶을 때.

  • 다중 테넌시(Multi-tenancy)
    여러 사용자가 서로 격리된 상태로 애플리케이션을 사용해야 할 때.

변경 시 컨트롤러나 서비스는 각 요청마다 새로운 인스턴스를 생성

@Injectable({ scope: Scope.REQUEST }) // scope 설정
export class MyService {
  // 이 서비스는 요청마다 새로운 인스턴스가 생성됩니다.
}
profile
프로 개발자가 되기 위해 뚜벅뚜벅.. 뚜벅초

0개의 댓글