인프런 커뮤니티 질문&답변
@ResponseBody 로 도메인 레이어의 MemberRegisterRequest 를 그대로 사용하는 것에 대해서
작성
·
138
1
안녕하세요. 토비님, 강의 잘 듣고 있습니다. 🙂
오늘은 강의 내용에서 좀 굉장히 의외인 부분을 발견해서 질문드립니다.
강의 #41. MemberApi와 웹 단위 테스트 에서 MemberRegisterRequest 가 domain 레이어에서 정의했던 클래스임에도, @RequestBody 파라미터 그대로 쓰셨는데, 이 부분이 많이 의외고 우려가 되었습니다.
저렇게 하면 MemberRegisterRequest 클래스의 코드 변경이 api 스펙 변경을 의미하는지가 코드리뷰 상에서 쉽게 보이지 않고 숨겨질 수 있다는 염려가 됩니다.
실제로 MemberRegisterRequest 에 필드를 추가해서 PR 을 올리면 코드리뷰어가 봤을 때 domain 레이어의 특정 모델에 필드가 추가됐을 뿐인 작은 변경으로 보일 것입니다. 그래서 그것이 어느어느 API 의 스펙에 영향을 주는지 알기가 너무 어려울 것 같습니다.
그래서 저는 API 의 스펙이 되는 Request, Response DTO 의 경우 반드시 클래스를 별도로 분리해야한다고 생각합니다.
API 스펙은 server 마음대로 변경할 수 있는 서버만의 코드가 아니라 client 와의 계약 문서라고 보기 때문입니다.
그래서 Request/Response 같이 백앤드 엔지니어가 함부로 변경할 수 없는 영역과 맘대로 변경 가능한 영역을 분리해서, 어플리케이션과 도메인 로직의 변화가 API 스펙 변경으로 인한 장애 걱정으로 이어지지 않게 하는 것이 중요하다고 생각합니다.
이게 근데 단순히 클래스 분리만 해둬도 PR 에서 API 스펙이 어떻게 바뀌는지 쉽게 트래킹이 가능해지기 떄문에 이 부분 만큼은 번거롭더라도 실보다 득이 훨씬 많아서 꼭 분리해야한다고 생각해왔습니다.
이 부분에 대해서 어떻게 생각하시는지 궁금합니다.
답변 2
5
말씀하신 내용에 공감합니다. 이번 강의에선 계층간 의존관계를 지키는 가장 단순한 방식을 선택했기 때문에 API 요청을 받는 별도의 클래스를 사용하지는 않았습니다. 우선은 그래도 문제없다고 생각을 했고요. 이후에 도메인까지 연결되는 오브젝트와 API 스펙이 분리가 되기 시작하면 그때 간단히 리팩터링을 해서 분리하고 매핑하는 방식으로 변경 될거라고 생각하고 있습니다.
API 스펙은 외부 시스템과의 계약이기 때문에 도메인/애플리케이션 로직의 변경이 그에 영향을 끼치면 안 된다라고 하셨는데요. 저는 이 부분은 100% 동의하기는 힘듭니다.
도메인은 우리가 만드는 서비스의 가장 중요한 핵심 지식을 정리해서, 모든 개발자와 도메인 전문가까지 모여서 만든 것입니다. 따라서 이 도메인 모델을 만들고 그 지식을 공유하는 데 API를 사용할 프론트 엔드 개발자도 포함될 겁니다.
그렇다면 사용자 등록에 새로운 필수 정보가 추가되는 결정이 일어날 때도, 모든 개발자들이 이 지식을 공유하게 되고 동의를 해야겠죠. 그러면 자연스럽게 API의 변경, 계약의 수정이 필요하다는 것까지 이어지지 않을까요. API 스펙이 도메인과 무관한 다른 기술적인 정보를 주고 받는 것도 포함되지만, 도메인과 연결되는 기능을 구현하기 위한 API였다면 당연히 그 변경이 필요하다는 것도 같이 이야기 될 겁니다.
만약 필수 정보의 추가가 아니고, 혹은 도메인과 상관없지만 뭔가 가공된 정보를 Request 오브젝트에, 어떤 개발자가 추가했다고 생각해보죠. 그러면 그 사람은 그 정보가 어디서 만들어지는 것인지를 확인하지 않고, 그냥 이런 정보도 필요하니까 넣었다, 뭐 이걸 쓰는 클라이언트(여기서는 웹 계층, 더 나아가서 API를 쏘는 프론트엔드)가 알아서 넣든지 말든지 이렇게 생각할리는 없고, 그런식의 변경이 PR로 올라왔다면 리뷰 과정에서 너무 자연스럽게 의문이 제기될 거라고 봅니다. Request가 단순히 특정 계층을 이동하는 데이터를 묶은 DTO가 아니라 도메인의 구성요소였다면 더더욱 그렇죠. 회원 등록을 할 때는 이런 정보가 필수로 필요하고 이런 규칙을 따라야 한다를 담은게 도메인 계층의 일종의 VO인 MemberRegisterRequest니까요.
또, API의 파라미터로 사용되고, 만약 필수 정보가 여기에 포함되어 있다면 null 체크나 empty 체크가 들어가겠죠. 만약 API 쪽의 변경이 필요한데 그걸 무시하고 Request 클래스를 변경했다면 자연스럽게 테스트가 실패할 겁니다. 그런 채로 배포될 가능성은 오히려 낮겠죠.
반대로 API의 RequestDTO를 만들었다고 생각해보죠. 이때는 오히려 논리적인 버그가 발생할 가능성이 생깁니다. MemberRegisterRequestDTO에서 애플리케이션 포트로 넘길 때 필요한 MemberRegisterRequest로 데이터를 매핑/복사하는 코드가 있을텐데, 거기서 값을 넣지 않아도 애플리케이션 영역에서 다시 체크하지 않으면 문제가 되지 않을 수도 있으니까요. 물론 지금 예제 코드 스타일로 작성했다면 최조 도메인까지 필수 항목 여부는 체크를 합니다만, 추가한 항목이 필수가 아니라 선택인 경우라면, 이게 API에 반영이 되지 않았음에도 아무 문제없이 코드가 돌아가지만, 도메인의 기능을 변경했음에도 이게 API에 반영이 안 됐는데도 아무 문제가 없다는 게 더 큰 문제가 아닐까요. 에러나는 장애보다, 에러가 없는 논리적인 버그로 데이터가 맞지 않는 상황, 기능의 적용이 제대로 됐는지 확인 안 되는 것이 더 큰 문제일 수도 있습니다.
이런 모든 것을 고려해서 사실 선택을 해야 하는데, 적어도 이번 강의에서 작성한 코드 수준에선 API 요청은 별도의 클래스로 꼭 만들어야 한다라는 팀 차원읜 코딩 규칙이 있지 않다면 일단 선택할 수 있는 가장 심플하고 명확한 방식이었다고 보셔도 좋을 것 같습니다. 앞으로 기능이 계속 발전하고, 새로운 관점이나 문제가 보인다면 그때 바뀔 수도 있겠네요.
0
안녕하세요, 인프런 AI 인턴입니다. woonge님께서 주신 질문에 대해 답변드리겠습니다.
강의에서 사용된 MemberRegisterRequest를 도메인 레이어에서 직접 웹 API의 요청에 사용하는 방식이 의외로 느껴지신 것 같습니다. 질문자님께서는 API 스펙과 도메인 모델의 변경이 서로 독립적으로 관리되어야 하며, 분리된 Request/Response DTO를 사용해야 API의 변경 사항을 명확히 파악할 수 있다고 말씀하셨습니다.
MemberRegisterRequest를 도메인 레이어와 API에서 사용에 대한 우려
API 스펙과 도메인 모델 간의 혼동: 말씀하신 대로 도메인 레이어의 모델을 API 스펙으로 그대로 노출할 경우, 내부 로직의 변경이 외부 API 스펙의 변경을 초래할 수 있는 문제가 발생할 수 있습니다. 이러한 방식은 리뷰어가 코드 변경으로 인해 API 스펙에 미치는 영향을 쉽게 파악하기 어렵게 만들 수 있습니다.
역할 및 책임 분리: 도메인 모델과 API DTO를 분리하면 각 레이어의 변경을 독립적으로 관리할 수 있으며, API의 요청/응답 규격을 명확히 하고 변경 사항을 추적하는 데 도움을 줍니다.
분리의 이점
변경 추적: DTO를 사용하는 경우, API에 관련된 모든 변경이 분리된 객체를 통해 명확해지고, 이로 인해 코드 리뷰가 더 투명해지고 관리하기 쉬워집니다.
계약 유지: API는 클라이언트와의 계약이라고 할 수 있으므로, 이런 계약은 신중히 관리되어야 합니다. 즉, 클라이언트가 의도된 방식으로 서버와 상호작용하도록 보장할 수 있습니다.
강의의 의도와 실무적인 고려사항
강의에서 보여준 방식은 간단한 애플리케이션 구조를 가정하여 모든 레이어를 통해 단일 객체를 사용함으로써 복잡도를 줄이고, 빠른 프로토타이핑을 염두에 두었을 수도 있습니다. 실무에서는 API의 안정성 및 계약 유지가 중요하므로, 안정성과 확장성을 고려하여 DTO를 분리하는 것이 일반적입니다.
유사한 강의의 질문과 답변
- MemberRegisterRequest 에 대해서: 이 링크에서는 비슷한 문제에 대해 강사의 답변을 찾을 수 있습니다. API의 설계 철학 및 실무적인 구현에 대한 깊이 있는 설명이 포함되어 있으니 참고하시면 도움이 될 것입니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.




