- 클라이언트가 Request(요청)을 하면 위의 사진처럼 Middleware -> Guard -> Interceptor -> Pipe -> Contoller(Module) -> ExceptionFilter -> Interceptor의 순서대로 Response(응답)을 하게 된다.
- Interceptor는 요청과 응답 모두 적용이 된다.
- 사진의 Controller handler는 Module이라고도 부르며, 요청 로직을 처리하는데 Controller , Service , Repository 로 이루어져 있다.
✅ NestJS는 Dependency Injection (DI)과 Inversion of Control (IoC)를 활용하여 유지보수성과 모듈화를 극대화한다.
- DI는 클래스가 필요한 의존성을 외부에서 주입받는 디자인 패턴으로, 클래스 간의 결합도를 낮추고 테스트를 용이하게 한다. 클래스의 생성자에서 의존성을 선언하면 NestJS가 IoC 컨테이너를 통해 자동으로 주입해 준다.
class DatabaseService {
getConnection() {
return 'Database Connection';
}
}
class UserService {
private databaseService: DatabaseService;
constructor() {
this.databaseService = new DatabaseService(); // 직접 인스턴스를 생성
}
}
- 이 방식은 클래스 간의 결합도가 높아지며, UserService는 DatabaseService에 강하게 의존하게 된다.
@Injectable()
class DatabaseService {
getConnection() {
return 'Database Connection';
}
}
@Injectable() // IoC Container에 등록
class UserService {
constructor(private databaseService: DatabaseService) {} // 생성자에 주입
- DatabaseService는 UserService의 의존성이며, NestJS가 자동으로 주입한다.
- DI를 이용하여 UserService는 DatabaseService의 생성 방법을 몰라도 되고, 외부에서 필요한 의존성을 주입받기 때문에 결합도가 낮아지고 테스트가 쉬워진다.
Inversion of Control
은 객체의 생성과 라이프사이클을 프레임워크인 NestJS의IoC Container
에서 처리한다.IoC Container
는 모듈안에 선언해놓은 클래스들을 provider를 통해 자동으로 인스턴스를 만들어놓는다.- 어떤 클래스에서 다른 클래스의 인스턴스가 필요하다면
IoC Container
에서 주입해준다.
import { DatabaseService } from './database.service';
import { UserService } from './user.service';
@Module({
providers: [DatabaseService, UserService],
exports: [UserService],
})
export class AppModule {}
@Module
,@Injectable
애노테이션을 사용하여 NestJS의IoC Container
에 등록해서 사용한다.