Nest.js는 백엔드 서버를 구축하기 위한 Node.js 프레임 워크이다.
TypeScript를 지원하며, 순수 JavaScript로도 사용가능하다.
$ nest g module catsCatsModule
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 할 수 있다
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() 선언
https://velog.io/@ayoung3052/Nest.JS%EC%9D%98-%EB%8F%99%EC%A0%81-%EB%AA%A8%EB%93%88
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';
}
}
findAll @Res() response @HttpCode(204) / @HttpCode(HttpStatus.CREATED)@Header('Cache-Control', 'no-store')@Redirect('https://nestjs.com', 301)
@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) 등으로 타입을 지정할 수 있다.$ 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;
}
}
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();
}
}
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에서는 이러한 명시적인 모듈 개념이 없으며, 패키지와 클래스 간의 구조로 의존성을 관리합니다.
Service: 제품
Provider: 공급자
controller 소비자
공급자가 제품을 제공해줘야 소비자가 사용할 수 있듯, Provider에 Service를 등록해주어야 Controller에서 주입받아 사용이 가능하다.
Service 선언
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 {}
NestJS는 싱글톤 패턴을 기본으로 사용한다.
대부분의 서비스는 애플리케이션 전반에서 하나의 인스턴스만 공유한다.
요청 간의 상태를 공유한다.
- 단일 스레드 기반의 이벤트 루프 모델을 따른다
데이터베이스 연결 풀 관리, 글로벌 상태 유치 측면에서 유리하다.
필요 상황
요청별 캐싱(Request-scoped caching)
요청마다 다른 데이터를 유지해야 하는 경우.
요청 추적(Request tracking)
각 요청에 대해 고유한 정보를 저장하고 싶을 때.
다중 테넌시(Multi-tenancy)
여러 사용자가 서로 격리된 상태로 애플리케이션을 사용해야 할 때.
변경 시 컨트롤러나 서비스는 각 요청마다 새로운 인스턴스를 생성
@Injectable({ scope: Scope.REQUEST }) // scope 설정
export class MyService {
// 이 서비스는 요청마다 새로운 인스턴스가 생성됩니다.
}