인프런 커뮤니티 질문&답변

인생은회전목마님의 프로필 이미지
인생은회전목마

작성한 질문수

실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화

OSIV와 성능 최적화

어플리케이션 서비스와 도메인 서비스의 구성

작성

·

513

·

수정됨

0

안녕하세요.

OSIV 강의 후반부 내용에서 규모가 비교적 큰 프로젝트에서는 도메인 계층과 더불어 그 앞단에 애플리케이션 계층을 추가하는걸 고려해보라고 말씀주신 내용이 있었는데요. 이게 제가 찾고 있는 해답이 아닐까 싶어 조금 더 자세히 알고 싶어 질문 드립니다. 질문이 조금은 장황해도 너그러히 이해주시면 감사드리겠습니다.

 

최근에 개인 프로젝트를 수행해보면서 제가 학습해온 개념들(JPA, DDD, MSA)이 중점적으로 다루는 내용이 다르다보니 프로젝트 구성에서 혼란을 겪어오고 있습니다.

현재 개인 프로젝트 패키지 구조는 제가 느끼기에 가장 와닿았던 controller - application - domain - repository로 나뉘어 개발하고 있습니다.

이때 application 계층의 역할은 하나의 요구사항(가입, 해지 등)을 해결하기 위해 필요한 하위 계층의 애플리케이션 서비스들을 호출하는 facade를 구성합니다. 또, domain에서는 도메인 객체와 더불어 해당 도메인의 애플리케이션 서비스를 통해 비즈니스적 처리를 추상화하여 표현하고, 데이터 핵심 데이터 처리를 repository에 위임하도록 구성했습니다.

다만 이해가 안 갔던건 트랜잭션을 처리 계층에 대한 내용인데요. 제가 본 msa 도서에서는 facade에서 수행되는 애플리케이션 서비스 각각이 서로 다른 도메인 처리이므로 application 계층이 아닌, domain 메소드 단위로 트랜잭션이 구성되어야한다더라구요.

그런데 사실 제가 개발하고 있는 프로젝트는 MSA 구조가 아니고, 여러 에그리거트가 복합된 구조이기에 위 구조와 사상을 가지고 개발하기 어렵다는 생각이 들었습니다. 또한, 서로 다른 도메인의 애플리케이션 서비스간에 호출관계에서도 어려움을 겪었는데요.

예를 들어, 두 user가 하나의 group을 구성하는 서비스를 만들 때도 groupService라는 group에 종속된 애플리케이션 서비스에서 두 사용자 정보를 불러오는 userService 주입하자니, 서로 상이한 서비스간에 불필요한 의존성이 생기고, 같은 레벨의 서비스를 참조하는 것이 어색하다고 느껴졌습니다. 그래서 facade 계층에서 두 서비스를 주입하여 그룹생성 절차를 처리하자니 한 트랜잭션에 처리되어야한다고 생각하는 그룹 생성 처리 절차에서 회원, 그룹 서비스의 트랜잭션이 분리되니 이상하다고 생각했습니다.

 

드디어 본격적인 질문인데요.

 

  1. 혹시 영한님께서 말씀하신 애플리케이션 계층이 이렇게 도메인에 종속된 두 개 이상의 서비스가 함께 쓰여야 할 때 쓰이는 것이 맞을까요?

  2. 맞다면 controller - application - domain - repository 의 계층구조에서 facade가 들어가던 application에 해당 복합(?) 서비스를 구현하고, 해당 서비스에 대한 dto객체정도들만 구현하면 되는걸까요?

 3. 굳이 어플리케이션 계층이 필요로 하지않은 하나의 도메인에만 종속된 기능들을 호출구조를 어떻게 가야할까요?

애플리케이션 계층을 도입한 상황에서 controller에서 domain 계층을 바로 호출하는 것은 일관성이 없어보이고, 또 일관성을 맞추기위해 application 계층에서 도메인 계층으로 BYPASS하는 객체를 만드는 것도 비효율적으로 보이긴합니다. 각각의 케이스에 어떻게 가는게 좋을까요?

 

답변 2

0

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. 인생은회전목마님

AI 인턴이 잘 답변을 해주었는데요.

여기에 추가로 몇가지 말씀드리자면 트랜잭션의 목적 자체가 여러 로직을 하나의 트랜잭션으로 묶어서 처리하는 것입니다. 따라서 이 구조의 경우 애플리케이션 계층에서 트랜잭션을 묶을 수 있습니다.

그리고 항상 애플리케이션 계층을 만들어야 하는가? 라면 꼭 그렇지는 않다 생각합니다. 의존관계가 단방향으로 흐를 수 있다면 컨트롤러에서 바로 리포지토리를 호출해도 된다 생각합니다. 물론 이 부분은 프로젝트 구조와 팀의 협의에 따라 달라집니다.

감사합니다.

0

안녕하세요, 인프런 AI 인턴입니다.

인생은회전목마다님의 질문에 대해 답변 드리겠습니다.

  1. 네, 맞습니다. 애플리케이션 계층은 여러 도메인 서비스를 조합하고 흐름을 제어하는 역할을 합니다. 이 계층은 복잡한 비즈니스 로직이나 트랜잭션을 관리하는 경우에 특히 유용하며, 각기 다른 도메인의 서비스가 함께 작업해야 할 때 해당 로직을 캡슐화하여 사용되곤 합니다.

  2. 애플리케이션 계층에서는 복잡한 비즈니스 로직을 조정하고, 필요한 도메인 모델 간의 플로우를 관리합니다. 또한, 트랜잭션의 범위도 이 계층에서 정할 수 있습니다. DTO 객체를 이 계층에서 생성하고, 이를 이용해 컨트롤러와 도메인 사이의 데이터 전달 역할을 합니다.

  3. 하나의 도메인에만 종속된 기능의 경우, 애플리케이션 서비스 계층을 경유하지 않고 도메인 계층을 직접 호출하는 것이 더 효율적일 수 있습니다. 다만, 이 경우에도 애플리케이션 계층을 통해 일관된 접근 방식을 유지하는 것이 유지보수성과 확장성 측면에서 바람직할 수 있습니다. 따라서 단순히 도메인 로직만 호출하는 서비스 레이어를 만들고, 컨트롤러에서는 이들을 호출하는 것도 좋은 방법입니다.

컨트롤러에 도메인 계층을 바로 호출하는 것은 레이어의 추상화 원칙에 어긋날 수 있으며, 애플리케이션의 복잡도가 증가하면 변경에 취약해질 수 있습니다. 효율과 일관성을 모두 고려하여, 적절한 레이어링과 서비스 추상화가 필요합니다.

마지막으로 강의와 직접 연결되는 언급은 없지만, 인프런의 지식공유자 김영한님의 강의에서 이러한 내용들을 자세히 배울 수 있을 것 같습니다. 추가적으로 학습하실 수 있도록 관련 문서의 링크를 참조해보시길 권장드립니다.

스프링, JPA 강의 자주 하는 질문

도움이 되셨길 바라며, 애플리케이션 아키텍쳐를 구성함에 있어 귀하의 프로젝트에 적합한 최선의 방향을 찾으시길 바랍니다.

인생은회전목마님의 프로필 이미지
인생은회전목마

작성한 질문수

질문하기