진행하고 있는 프로젝트에서 멀티모듈을 적용하며 모듈 간 순환참조 이슈가 발생했고,
그 해결 과정을 기록해두려 한다.
현재 상황
- `Owing-Domain`: 애플리케이션의 핵심 도메인 로직을 담당하는 모듈이다. 주요 엔티티, 비즈니스 규칙, 도메인 서비스 등을 포함한다. Owing-Domain은 애플리케이션의 핵심 비즈니스 규칙과 모델을 정의하고, 가능한 한 외부 시스템(API, 데이터베이스, UI 등)에 종속되지 않아야 한다.
- `Owing-Api`: 애플리케이션의 외부 진입점 역할을 하며, HTTP 요청을 처리하고 응답을 반환하는 등 애플리케이션의 외부와 상호작용하는 부분을 담당하는 모듈이다. 컨트롤러, DTO, 요청/응답 매핑 로직 등을 포함한다.
즉, 아래처럼 Owing-Api 모듈이 Owing-Domain 모듈을 참조하고 있는 상황이다.
모듈 간 순환참조 발생
이러한 상황에서, 아래와 같이 DomainService에서 Dto를 직접 참조하니 다음과 같은 에러 메시지가 나타났다.
`UniverseDomainService.java`
@Transactional
public Universe updateUniverse(Universe universe, UpdateUniverseRequest updateUniverseRequest) {
universe.updateName(updateUniverseRequest.getName());
universe.updateDescription(updateUniverseRequest.getDescription());
universe.updateImageUrl(updateUniverseRequest.getImageUrl());
return universe;
}
순환참조가 발생할 가능성이 있다는 것인데, 멀티모듈을 처음 접해보니 각 모듈간 참조 관계가 익숙치 않았다.
따라서 DomainService에서 Dto를 참조하는 모습을 시각화해보니 순환참조가 발생한 이유를 알 수 있었다.
Owing-API에서 Owing-Domain을 참조하는 방향으로 서비스가 흘러가야 하는데, 그 반대 방향으로의 참조가 생긴 것이다.
순환참조 해결
이전 코드처럼 DomainService에서 Dto를 직접 참조하는 것이 아닌, Universe 객체를 참조하는 방식으로 해결했다.
Mapper를 이용해 수정할(=새로운) Universe 객체를 조립한다.
`UniverseDomainService.java`
@Transactional
public Universe updateUniverse(Universe oldUniverse, Universe newUniverse) {
Universe updatedUniverse = oldUniverse.updateUniverse(newUniverse);
return updatedUniverse;
}
`UpdateUniverseUseCase.java`
@Transactional
public UniverseShortInfoResponse execute(Long universeId, UpdateUniverseRequest updateUniverseRequest) {
Universe oldUniverse = universeAdaptor.findById(universeId);
Universe newUniverse = universeMapper.toEntity(oldUniverse, updateUniverseRequest); // Mapper를 이용해 객체 생성
Universe updatedUniverse = universeDomainService.updateUniverse(oldUniverse, newUniverse);
return universeMapper.toShortInfoResponse(updatedUniverse);
}
'✍️ 개발 기록' 카테고리의 다른 글
[👀 Owing] PostgreSQL 도입기 (feat. MySQL과의 차이) (0) | 2024.11.05 |
---|---|
[👀 Owing] Java Record 도입기 ☕️ (0) | 2024.11.05 |
[👀 Owing] Presigned URL을 이용하여 S3로 파일 업로드 (0) | 2024.10.31 |
[👀 Owing] S3에 파일을 업로드하는 세 가지 방법 (MultipartFile, Stream, PresignedURL) (0) | 2024.10.31 |
[👀 Owing] Framer motion 애니메이션 적용기 (0) | 2024.09.27 |