@Controller('cats')
export class AppController {
constructor(private readonly appService: AppService) {}
// localhost:3000/cats/info
@Get('info/:id/:name')
getHello(
@Req() req: Request,
@Body() Body,
@Param() param: { id: string; name: string },
): string {
console.log(param);
return this.appService.getHello();
}
}
NestJS는 클래스 내부에서 생성자로 초기화를 한 다음 이를 (this 초기화 없이) 바로 인자로 받아서 사용한다. 이러한 패턴이 의존성 주입(Injectable) 패턴이다. 의존성 주입은 공급자와 깊은 연관이 있다. 공급자의 주요 특성 중 하나가 종속성이 있는 제품들을 주입할 수 있다는 것이기 때문이다. 즉, controller는 이들을 주입받아서 사용하는 것이다. 또한 Nest 클래스의 대부분은 공급자로 취급될 수 있다. (서비스, 리포지토리, 팩토리 등 / 이것들은 종속성을 가진다는 의미와도 같다) 공급자로 취급되는 것들은 @Injectable()
데코레이터로 표현한다.
아래 코드는 AppController
의 공급자로 사용되고 있는 app.service.ts
파일 코드다. 의존성 주입 데코레이터가 달린 것을 확인할 수 있다.
import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
}
AppController
를 소비자, appService
를 제품이라고 가정할 때, AppController
가 공급된 제품을 appService
라는 인스턴스로 의존성 주입을 받아서 해당 제품을 사용할 수 있다. 이처럼 제품을 공급해 주는 공급자(providers)는 app.module.ts
안에서 확인할 수 있다.ㅤ
@Module({
imports: [],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
만약 providers
안에 있는 [AppService]
를 제거하면 AppController
의 의존성인 appService
가 resolve되지 않아 오류가 발생한다. 제품(appService)에 대한 공급자(AppService)를 찾아가고 제품을 받아 소비자(AppController)에게 넘겨주어야 하는데, 제품의 공급자가 없으니 controller에서 제품을 사용할 수 없게 되는 것이다. 관계를 순전히 이해하기 편하게 만들면 아래의 표와 같다.
ㅤㅤㅤ공급자ㅤㅤㅤ | ㅤㅤㅤ공급자가 제공해 준 제품ㅤㅤㅤ | ㅤㅤㅤㅤ소비자ㅤㅤㅤㅤ |
---|---|---|
AppService | appService | AppController |
NestJS은 객체 지향 프로그래밍이다. 객체 지향 프로그래밍의 핵심 목표는 실생활과 유사하게 코드를 짜는 것이다. 의존성 주입을 하게 되면 실생활과 같은 공급자-소비자의 관계가 명료하게 나타난다. 이렇게 함으로써 유지보수도 간편해지고 확장성 있게 더 탄탄한 백엔드 애플리케이션을 짤 수 있게 된다.