NestJS 프레임워크를 공부하기 위해서 개인 프로젝트 개발에 도전하였다. 가볍게 대중적인 게시판 만들기부터 시작하였다. 이 게시판 개인 프로젝트에서 articles 모듈과, users 모듈 사이에 순환 참조 문제가 발생하여 어떻게 해결할지 고민했던 과거를 공유하고자 글을 작성하게 되었다.
기존 프로젝트 모듈 구조
개인 프로젝트에서 처음에는 크게 3가지 모듈을 나누어 작업을 하였다. 모듈은 다음과 같은 기능을 한다 :
- AuthModule : JWT 인증을 위한 모듈. 회원가입, 로그인을 담당함. 회원가입 시에
@Post('/register')
엔드포인트에서 UsersModule에 접근하여 User 객체 생성. - UsersModule : 직접적으로 User 객체를 생성. Repository 디자인 패턴을 이용함.
- ArticlesModule : 직접적으로 Article 객체를 생성.
@Post('/article')
엔드포인트를 통해서 ArticlesModule에 접근하여 Article 객체 생성. Repository 디자인 패턴을 이용함.
ArticlesModule의 @Post('/article')
에서 article 객체를 생성한다. article 객체를 생성할 때, 하나의 article 인스턴스는 authorId 정보를 갖게 되는데, 이는 article 객체를 생성한 user의 id 정보이다. 따라서 ArticlesModule는 UsersModule을 import 해야하는 상황이 되었다.
ArticlesModule이 UsersModule을 참조하는 것은 문제가 되지 않지만, 기존에 UsersModule 또한 ArticlesModule을 import 하고 있었다. user 인스턴스는 자신이 만든 aritlce의
아이디들(지금은 삭제)
갯수를 저장하고 있기 때문이다.
따라서 순환 참조 문제가 발생하여 문제를 해결하기 위해서 두 모듈 사이의 상호작용을 처리하는 모듈인 UserArticleInteractionModule 을 만들기 시작했다.
순환 참조 문제 해결
이 모듈은 다른 두 모듈의 repository에 직접적으로 접근하지 않고, service에 접근하여 aritlce 생성 시에 userId 정보를 넘기고, user 에 PRIVATE or PUBLIC article 의 갯수 정보를 넘긴다.
쉽게 말해서 UserArticleInteractionModule에서만 ArticlesModule, UsersModule를 import하고, UserArticleInteractionService에서는 각 ArticlesService, UsersService를 불러와서 순환 참조를 없애었다.(ArticlesModule, UsersModule은 이제 서로를 import하지 않음.)
export class UserArticleInteractionService {
constructor(
private readonly usersService: UsersService,
private readonly articlesService: ArticlesService,
) {}
...
}
따라서 기존에 article 객체를 직접적으로 생성하는 것을 ArticleModule에서 했지만, 순환 모듈 없이 userId와 articleId를 공유하기 위해서 아래와 같이 에서 article CRUD를 만들게 되었다.
article CREATE :
async createArticleForUser(
userId: string,
createArticleDto: CreateArticleDto,
) {
const newArticle = await this.articlesService.create(createArticleDto);
if (newArticle) {
// service
}
return newArticle;
}
각 모듈은 독립적으로 책임을 분리하는 것이 원칙적으로 좋지만, 어쩔 수 없는 경우는 순환 참조를 피하기 위해서 두 개의 모듈이 상호작용을 하는 또 다른 모듈을 만드는 방법을 사용하는 것도 개인적으로 나쁘지 않은 것 같다.
마무리
공부한 것을 저만의 방식으로 작성한 글입니다. 따라서 틀린 정보가 공유될 수도 있으니 참고만 하되 꼭 공식문서를 통해서 공부하시길 바랍니다! 또한 틀린 부분 지적해주시면 감사하겠습니다!
'Web Development' 카테고리의 다른 글
왜 Transaction이 필요하고 중요할까? (3) | 2025.08.17 |
---|---|
Google OAuth 다중 계정 로그인 문제 해결 (5) | 2025.08.07 |
JWT vs 세션, 어떤 로그인 방식을 선택할까? (0) | 2025.07.22 |
Web Socket(웹 소켓)과 HTTP (0) | 2025.02.11 |
비동기 함수(async function), Promise 란? (0) | 2024.03.12 |