Nest.js를 사용해서 개발을 진행하다보면 도메인 모델 계층에서 정말 많은 모듈로 분리해서 개발을 진행하게 된다. 명확한 명칭으로 모듈을 분리하게 되면 해당 모듈이 어떤 역할을 하는지 쉽게 알 수 있어 매우 좋지만 서로 다른 모듈끼리의 의존성을 조금만 신경쓰지 않으면 순환참조와 같은 문제가 발생한다.
순환참조란?
순환참조는 객체, 데이터, 모듈, 함수 등이 서로를 참조하는 것을 말한다. 간단한 자바스크립트 코드로 예시를 들면 아래와 같다.
let obj1 = {};
let obj2 = {};
obj1.otherObj = obj2;
obj2.otherObj = obj1;
이처럼 서로를 참조하는 경우 프로그램의 복잡성을 증가시키고 디버깅을 어렵게 만든다. 또한 메모리 누수, 스택 오버플로우, 무한 루프 등의 문제가 나타날 수 있다.
Nest.js에서 순환참조
Nest.js는 객체간의 의존성 주입을 통해 동작한다. 객체간의 의존성을 지정해주고 런타임을 돌릴때 만약 나도 모르게 순환참조 구조로 구현해놨다면 런타임 자체에 문제가 생기게 된다.
해결 방법
그럼에도 불구하고 구현을 하다보면 어쩔 수 없이 순환참조가 나타날 수 밖에 없다. 그럴 땐 다음과 같은 방법으로 해결 할 수 있다.
1. Nest.js 에서 제공하는 forwardRef()
@Module({
imports: [forwardRef(() => UserModule)],
controllers: [AuthController],
providers: [AuthService],
exports: [IAuthRepository],
})
@Module({
imports: [forwardRef(() => AuthModule)],
controllers: [UserController],
providers: [UserService],
exports: [IUserRepository],
})
위 코드 처럼 Nest.js의 module에서 imports에 forwardRef() 메서드로 서로 지정해주게 되면 순환참조가 있어도 런타임을 문제없이 실행할 수 있다. 하지만 이 방법은 정말 어쩔 수 없을 때 사용해야하고 최대한 아래와 같은 방법들로 해결해줘야 한다.
2. 객체와 객체 사이에 중간 객체를 집어 넣어 순환참조 없애기
여기서 말하는 중간 객체는 interface나 abstract 뿐만 아니라 기능적으로 동작하는 class 도 포함이다. 계층간의 결합도를 낮추기 위해서 중간 객체를 추가하게 되면 재사용성이 높아지는 장점도 있다.
3. 의존성 역전 원칙으로 순환참조 없애기
보통 클린아키텍처에서 비즈니스 로직을 보호하기 위해 interface 계층 (추상화 계층)을 port로 사용하는데 이 방법으로 순환참조를 없앨 수 있다.
4. 순환참조 일어나는 클래스 합치기
개인적으로 가장 손쉽게 순환참조를 없앨 수 있는 방법은 두 클래스를 그냥 합쳐버리는 것이다. 애초에 순환참조가 일어난다는 것은 클래스를 쪼갤 필요가 없는 것일 수도 있기 때문에 그냥 합치면 순환참조가 해결된다.
'NestJS' 카테고리의 다른 글
Nest.js 라이프사이클 (0) | 2023.06.20 |
---|---|
Express에서 DI 프레임워크 만들어보기 (0) | 2023.05.04 |
Nest.js에서 모듈간의 의존성 관리하기 (0) | 2023.04.19 |
AuthGuard 예외처리 조건 만들기 (0) | 2023.04.19 |
Nest.js 에서 역직렬화 하기 (0) | 2023.03.14 |