NestJS는 모듈과 서비스를 효과적으로 구성하고 관리할 수 있는 강력한 기능을 제공합니다.
오늘은 NestJS에서 서비스를 공유하는 두 가지 방법인 의존성 주입(Dependency Injection)과 모듈 임포트에 대해 알아보겠습니다.
NestJS는 모듈과 서비스를 사용하여 애플리케이션을 구성합니다.
모듈은 애플리케이션의 부분을 나타내며, 서비스는 비즈니스 로직을 처리하고 데이터를 관리합니다.
상황 가정
1. Flowers와 Places라는 기능이 있다고 가정 (nest g resources flowers, nest g resources places)
2. FlowersController에서 PlacesService를 사용하고 싶음
3. 단, PlacesService를 새로 생성하는 것이 아닌 하나의 PlacesService로 공유해서 사용해야 함
의존성 주입(Dependency Injection)
의존성 주입을 사용하면 서비스를 다른 컴포넌트로 주입할 수 있습니다.
이를 통해 서비스를 공유할 수 있습니다.
@Controller('flowers')
export class FlowersController {
constructor(
private readonly flowersService: FlowersService,
private readonly placesService: PlacesService // 의존성 주입
) { }
...
}
모듈 exports
PlacesModule에서 사용 중인 PlacesService를 다른 모듈에서도 사용할 수 있도록 exports 해줍니다.
@Module({
controllers: [PlacesController],
providers: [PlacesService],
exports: [PlacesService] // exports
})
export class PlacesModule {}
모듈 imports
PlacesService를 사용하고 싶은 다른 모듈에서 PlacesService를 exports 한 Module인 PlacesModule을 import 해줍니다.
‼️ PlacesService를 사용하고 싶다고 PlacesService를 imports 하거나 providers로 등록하는 것이 아닙니다!
@Module({
imports: [PlacesModule], // 주의 !!
controllers: [FlowersController],
providers: [FlowersService],
})
export class FlowersModule {}
사용해보기
FlowersController의 findAll을 호출 시, FlowersService.findAll과 PlacesService.findAll이 둘 다 호출되도록 하고,
PlacesController의 findAll을 호출 시, PlacesService.findAll만 호출되도록 구성하겠습니다.
Service
@Injectable()
export class FlowersService {
private count = 0; // 카운트
findAll() {
return `This action returns all flowers : ${++this.count}`;
}
...
}
@Injectable()
export class PlacesService {
private count = 0; // 카운트
findAll() {
return `This action returns all places : ${++this.count}`;
}
...
}
Controller
@Controller('flowers')
export class FlowersController {
constructor(
private readonly flowersService: FlowersService,
private readonly placesService: PlacesService
) { }
@Get()
findAll() {
const flowers = this.flowersService.findAll(); // flowers의 findAll 호출
const places = this.placesService.findAll() // places의 findAll 호출
return `${flowers}</br>${places}`;
}
...
}
@Controller('places')
export class PlacesController {
constructor(private readonly placesService: PlacesService) {}
@Get()
findAll() {
return this.placesService.findAll(); // places의 findAll만 호출
}
...
}
테스트
GET localhost:3000/places 두 번 호출 후,
GET localhost:3000/flowers 호출했을 때의 결과는?
This action returns all flowers : 1
This action returns all places : 3
결론
하나의 인스턴스를 의존성 주입을 통해 서로 공유하여 사용할 수 있으며, 이를 통해 자원 절약과 일관된 상태를 유지할 수 있음.
번외
'모듈 imports' 단계에서 imports가 아닌 providers에 등록한다면?
@Module({
// imports: [PlacesModule], // 해당 코드 주석 처리
controllers: [FlowersController],
providers: [FlowersService, PlacesService], // PlacesService 등록
})
export class FlowersModule {}
위와 마찬가지로
GET localhost:3000/places 두 번 호출 후,
GET localhost:3000/flowers 호출했을 때의 결과는?
This action returns all flowers : 1
This action returns all places : 1
하나의 PlacesService를 공유하는 것이 아닌, 각각의 모듈에서 PlacesService를 생성하여 사용하게 된다.
참고
'개발일지 > Node.js' 카테고리의 다른 글
Prisma vs TypeORM 벤치마크 (0) | 2024.04.09 |
---|---|
TypeORM + MySQL8 AsText does not exist (0) | 2024.03.12 |
TypeORM - @Column({ unique : true }) vs @Unique() (0) | 2024.02.23 |
SQL Injection 방지 - 권장방식에는 다 이유가 있지.. (0) | 2024.01.31 |