Spring-Boot 프로젝트를 진행하던 중에 JPA를 사용하게 되었는데, DTO와 Entity를 굳이 나누어서 사용하는 이유가 알고싶어 찾아보고 알게 된 내용을 정리해두려고 한다.
Column을 필드로 가지는
객체이다.@Entity
public class Member {
private String id;
private String name;
private String phone;
예를 들어 DB의 Member라는 테이블에 id, name, phone이라는 컬럼이 있다고 하면, 이에 대응하는 Entity 클래스 Member는 위와 같은 필드들만 가질 수 있다.
만약 스프링에서 JPA를 사용한다면 Entity 클래스에 @Entity
어노테이션을 붙여 해당 클래스가 Entity 클래스임을 명시할 수 있다.
또한 id 컬럼에는 @Id
어노테이션을 붙일 수 있고 다른 컬럼 @Column
어노테이션을 붙여 다양한 기능을 사용할 수 있다.
DTO는 데이터를 Transfer(이동)
하기 위한 객체이다.
Client가 Controller에 요청을 보낼 때도 RequestDto의 형식으로 데이터가 이동하고, Controller가 Client에게 응답을 보낼 때도 ResponseDto의 형태로 데이터를 보내게 된다.
Controller와 Service, Repository 계층간 데이터 교환도 DTO의 형태로 이동하게 된다.
View에서 Controller로 넘어오는 데이터를 담거나, Controller에서 Service로 넘기는 데이터를 담거나 할 때 사용할 수 있다.
DTO는 그저 계층간 데이터 교환이 이루어 질 수 있도록 하는 객체로, 특별한 로직을 가지지 않는 순수한 데이터 객체이다.
DTO는 단순히 데이터를 옮기는 용도이기 때문에 굳이 Setter를 이용해 값을 수정할 필요가 없이, 생성자만을 사용하여 값을 할당한다.
그렇다면 데이터 이동시 왜 Entity와 DTO를 나누어 사용하는 것일까?
객체를 표현하기 위한 계층과 저장하는 계층의 역할을 분리하기 위해서 DTO를 사용한다.
Entity객체를 그대로 사용하면 개발자의 의도와는 다르게 데이터가 변경될 수 있다.
View(클라이언트)와 통신하는 DTO 클래스, 예를 들어 RequestDTO, ResponseDTO는 요구사항에 따라 자주 변경된다. 어떤 요청에서는 특정 값이 추가될 수도 있고, 특정값이 없을 수도 있다.
따라서 Entity 클래스와 분리하여 관리해야 한다.
도메인 설계가 아무리 잘 되있다 하더라도 원하는 데이터를 표시하기 쉽지 않을 수 있다.
예를 들어 Entity 클래스의 특정 컬럼들을 조합하여 특정 포맷을 출력하고 싶다고 하자.
Entity와 DTO가 분리되어 있지 않다면, Entity 클래스 안에 표현을 위한 필드나 로직을 추가하게 되어 객체 설계를 망가뜨릴 수 있다.
따라서 분리한 DTO에 표현을 위한 로직을 추가해서 사용함으로써 Entity의 도메인 모델링을 지킬 수 있다.