DTO, Entity and Mapper

hk·2022년 6월 27일
1

Spring

목록 보기
2/2

DTO(Data Transfer Object)란?

DTO(Data Transfer Object, 데이터 전송 객체)는 프로세스 간에 데이터를 전달하는 객체이다. 원격 인터페이스로 작업을 할 때, 호출에 따른 비용이 비싸기 때문에 요청의 횟수를 줄여야 하고, 이를 위해 한번의 요청에 더 많은 데이터를 전송해야 한다. 외부와 통신하는 프로그램에게 있어 호출은 큰 비용이며, 이를 줄이고 더욱 효율적으로 값을 전달할 필요가 있다. 이를 위해 데이터를 모아 한번에 전달하는 클래스를 DTO라고 한다.


Mapper의 기능

의존관계는 최대한 약하게 해야한다. (비용문제) 특히 컨트롤러와 서비스의 의존은 위험하다. -> 서비스 전용 DTO를 만들거나 Mapper를 통해 상호변환하여 의존관계를 줄여서 해결한다. Mapper(매퍼) 클래스는 DTO 클래스와 엔티티(Entity) 클래스를 서로 변환해준다.


DTO와 Entity를 Mapping해서 변환하는 이유

  1. 계층별 관심사 분리
  2. 코드 구성의 단순화
  3. REST API 스펙의 독립성 확보

Mapper 사용의 이점

  • Mapper에게 DTO 클래스 → 엔티티(Entity) 클래스로 변환하는 작업을 위임함으로써 Controller는 더이상 두 클래스의 변환 작업을 신경쓰지 않아도 된다. 역할 분리로 인해 코드 자체가 깔끔해진다.

  • Mapper가 엔티티(Entity)클래스를 DTO 클래스로 변환해주기때문에 서비스 계층에 있는 엔티티(Entity) 클래스를 API 계층에서 직접적으로 사용하는 문제가 해결된다.

" 컨트롤러와 서비스 간 통신을 할 때, 컨트롤러가 뷰와 통신할 때 사용한 DTO를 그대로 사용하면 강한 의존이 생겨 위험하다. 그러나 DTO를 엔티티로 바로 바꿔서 전달하는 것 역시 적절하지 않을 수 있다. 만약 DTO 안에 toEntity 메서드를 만들거나, 엔티티 안에 toDto 메서드를 만들어서 변환을 한다면 둘 중 하나가 바뀌어도 서로를 수정해야 하고, 결과적으로는 컨트롤러와 모델(서비스)의 의존을 만들게 된다.

이를 해결하기 위해, Mapper라는 컨트롤러에 종속적인 클래스를 만든다.
이 클래스는 정적 유틸 클래스로, DTO를 엔티티로, 혹은 반대로 변환시켜주는 기능을 가지고 있다. Mapper를 사용하면 DTO와 엔티티는 서로를 모를 수 있고, 한쪽에 수정이 발생해도 Mapper만 고치면 된다. "


Controller가 클라이언트의 요청에 대한 응답으로 도메인 Model인 User를 넘겨주면 어떤 문제점이 있을까?

  • 도메인 Model의 모든 속성이 외부에 노출된다.
    UI 화면마다 사용하는 Model의 정보는 상이하지만, Model 객체는 UI에서 사용하지 않을 불필요한 데이터까지 보유하고 있다. 비즈니스 로직 등 User의 민감한 정보가 외부에 노출되는 보안 문제와도 직결된다.
  • UI 계층에서 Model의 메서드를 호출하거나 상태를 변경시킬 위험이 존재한다.
  • Model과 View가 강하게 결합되어, View의 요구사항 변화가 Model에 영향을 끼치기 쉽다.
    또한 User Entity의 속성이 변경되면, View가 전달받을 JSON 및 프론트엔드 Js 코드에도 변경을 유발하기 때문에 상호간 강하게 결합된다.

MapStruct

어떤 도메인 업무 기능이 늘어날때 마다 개발자가 일일이 수작업으로 매퍼(Mapper) 클래스를 만드는 것은 비효율적이므로, MapStruct를 사용한다. MapStruct는 DTO 클래스처럼 Java Bean 규약을 지키는 객체들 간의 변환 기능을 제공하는 매퍼(Mapper) 구현 클래스를 자동으로 생성해주는 코드 자동 생성기입니다.


MapStruct와 ModelMapper

Java에서 Object를 Mapping하는 라이브러리는 생각보다 많이 존재한다. 그 중에서 가장 많이 사용되는 Mapping 라이브러리에는 MapStruct와 >ModelMapper가 있다.

결론을 이야기하자면 ModelMapper가 여전히 많이 사용되고 있지만 ModelMapper는 Runtime시 Java의 리플렉션 API를 이용해서 매핑을 진행하기 때문에 컴파일 타임에 이미 Mapper가 모두 생성되는 MapStruct보다 성능면에서 월등히 떨어진다.

따라서 ModelMapper의 대안으로 MapStruct가 많이 사용되고 있는 추세이다.


출처
https://developer-ping9.tistory.com/261
https://kafcamus.tistory.com/12?category=912020\
https://jihyee.tistory.com/14
https://xlffm3.github.io/spring%20&%20spring%20boot/DTOLayer/

profile
cloud master가 될 거야! (not 석사)

0개의 댓글