본문 바로가기
Spring/Coding Convention

DTO 는 어떻게 구성하고, 변환해야 할까?

by domo7304 2022. 7. 13.

지난 번에 DTO 를 사용해야 하는 이유 를 정리해 본 후, 어떻게 매핑하면 될 지에 대해서도 한 번 정리해둔다면 내 생각을 말할 때 많은 도움이 될 것 같다고 생각했다.

DTO class 를 어떻게 구성하고 변환할 것인가
 1. 처음 공부했던 방식 (이동)
 2. 개선했던 방식 (이동)
 3. 각 방식에서의 장점과 단점, 내 생각 (이동)
 4. 그 당시와 지금의 생각 (이동)

 

1. 처음 공부했던 방식

처음 Spring Boot 를 접하고 공부를 시작할 때에는 위와 같이 DTO class 들을 작성했었다. DTO 디렉토리 아래에 나름 편하게 구분하고 싶어서 {POST / GET / PATCH / DELETE} + {작업내용} + {Req / Res} 와 같은 네이밍을 가져갔었다. Entity - DTO 매핑방식의 경우 각 class 안에 'toEntity()', 'toDto()' 등 필요한 메소드를 작성해주었었다.

DTO class 의 경우 '필요한 데이터 전송, 비즈니스 로직은 포함하지 않도록' 이라는 역할만 수행할 수 있다면 어떻게 구현하여도 크게 문제는 없을 거라고 생각하지만...

  1. 요청, 응답이 늘어날수록 DTO class 의 수가 늘어나서 보기에 깔끔하지 못하다.
  2. Entity - DTO 를 매핑하는 메소드가 각 class 에 들어있고, 계속 작성해주어야 하는 게 불편(?)했다.

크지는 않지만...이런 사소한 이유로 DTO 를 조금 더 예쁘게 관리할 수는 없을까 고민을 했었다.

2. 개선했던 방식

https://velog.io/@p4rksh/Spring-Boot에서-깔끔하게-DTO-관리하기

 

Spring Boot에서 깔끔하게 DTO 관리하기

우리는 스토리보드를 보고 Api 명세를 작성할 때 테이블 설계와 동시에 Request와 Response 등 DTO 디자인을 고민하곤 한다. 하지만 기획 당시 계획한 디자인을 준수하여 개발을 하다보면 프로젝트 패

velog.io

그렇게 고민하던 중 해당 글을 보고 '아 이거다' 싶었었다. 그 당시 (21년 11월..?) Java 문법에도 익숙하지 않았을 때여서 nested class 라는 개념을 생각하지도 못했었는데, 위 글에서의 문제상황이 정확히 나와 같은 상황이라고 생각하여 nested class 를 이용하여 dto 를 한 곳에 몰아넣기로 했다.

그런데 dto 를 한 곳에 몰아넣고 나니, Entity - dto 매핑을 어디서 해야하나 위치가 애매해졌다. 

기존방식: 각 dto class 안에서 mapping 진행

기존에는 각 dto class 내부에서 위처럼 매핑했었으니 말이다. 그렇게 자연스럽게 dto 를 매핑하기 위한 방법이 있을까 찾던 중

https://meetup.toast.com/posts/213

 

Object Mapping 어디까지 해봤니? : NHN Cloud Meetup

이 글에서는 Object Mapping 라이브러리인 MapStruct에 대해 소개합니다. NHN Forward 2019에서 발표한 내용에 대해 조금 더 자세히 설명합니다.

meetup.toast.com

https://www.baeldung.com/java-performance-mapping-frameworks

 

Performance of Java Mapping Frameworks | Baeldung

MapStruct comes out on top, followed by JMapper as a close second. The other libraries follow far behind: Orika, ModelMapper, and Dozer.

www.baeldung.com

위 두 링크를 참고하였고, java 의 대표적인 mapping framework 인 ModelMapper, MapStruct 중 두 번째 링크를 참조하여 MapStruct 를 사용하기로 하였다.

3. 각 방식에서의 장점과 단점, 내 생각

원래 방식의 장점으로는

  1. ModelMapper 든, MapStruct 든 새로운 mapper 에 대해 공부해야하는 시간 소요가 적다
  2. Java 에 익숙하지 않거나, Spring Framework 를 막 공부하기 시작했다면 더 직관적이고 좋을 것 같다

이 정도가 있을 것 같다. 하지만 나의 경우

  1. 개별 파일로 늘어나는 dto class 가 보기 불편했다 (너무 길어진다)
  2. dto 는 dto 끼리, mapper 는 mapper 끼리 일관성있게 관리하고 싶었다
  3. dto class 마다 mapper 를 작성해야하는데, 뭔가 대신해줄 수 있는 게 있지 않을까 궁금했다

위처럼 더 좋게 바꿀 수 있지 않을까 싶은 생각이 있었다.

개선한 방식의 장점 (nested class 로 dto 모으기, MapStruct 등 mapper 사용) 으로는

  1. MapStruct 의 경우 Entity 의 Column 과 dto 의 field 명이 같은 경우 자동으로 mapping 코드를 생성해준다. 개발 소요가 줄어든다. (실제로 MapStruct 가 구현해준 코드를 확인할 수 있다)
  2. 형식적 validation 을 할 때(@NotNull, @Min, @Size 등등...), dto class 를 일일히 눌러가며 확인할 때에 비해 nested class 로 dto 를 모아두니 한 화면에서 확인해볼 수 있는 게 편했다.

이 정도가 있다고 생각한다.

4. 그 당시와 지금의 생각

최근 (22.07.13.) dto 에 대해 다시 찾아보다가 Data Transfer Object, The DTO Pattern (Data Transfer Object) 두 링크에서 다음과 같은 글, 이미지를 보았고

Martin Fowler, Patterns of Enterprise Application Architecture
Bealdung, The DTO Pattern

작년 11월에는 어쩌다보니 mapper 를 따로 두게 되었지만, 지금 생각해보아도 dto mapping 을 위한 assembler 를 따로 두는 것은 좋다고 생각한다.

 

1. [링크] DTO 를 사용해야 하는 이유
2. [링크] DTO 는 어떻게 변환해야 할까?
3. [링크]
Nested Class 에 언제 static 을 붙여야 할까?

 

* 번외 - Domain Driven Design (DDD) *

https://buildplease.com/pages/repositories-dto/

 

A Better Way to Project Domain Entities into DTOs

Imagine you have a nicely designed Domain Layer that uses Repositories to handle getting Domain Entities from your database with an ORM, e.g. Entity Framework, into an MVC view or a Web API controller. Problem is, the Presentation Layer needs objects of a

buildplease.com

DTO 매핑에 대해 검색해보다가 정말 축약적이고 좋은 글을 찾아서 링크를 남긴다. 글에서는

  1. 왜 Repository 계층이 DTO 매핑에 대한 관심사, 책임을 가져서는 안되는가?
  2. 그렇다면 어디서 DTO assemble 을 진행해야 하는가?

두 가지에 대해 굉장히 짧고 간단하게 다루고 있다. 결국은 '도메인 주도 설계' 에 대한 이야기인데, 필요할 때마다 조금씩 관련 내용을 참고하고는 있지만 언제 한 번 DDD 에 대해 깊게 다뤄봐야겠다...

더보기

댓글