1 minute read

DTO 란?

Data Transfer Object, 데이터 전송 객체를 의미한다. 데이터를 주고 받을 때 사용하는 객체라는 의미인데, 서버가 클라이언트에 응답해줄 때 DTO를 사용해보려고 한다.

DTO 사용 전에는…

entity를 사용했다. 아래는 Account entity 코드 일부이다.


import ...

@Entity
@Data
@Table(name = "account")
@ApiModel
public class Account {
  @Id
  @Column(name = "id") 
  String id;
  
  @Column(name = "name")
  String name;

  @Column(name = "email")
  String email;

  @Column(name = "contact")
  String contact;
}

계정 정보를 담는 account table 정보를 entity로 생성한다. 클라이언트에 데이터 전송 시 이 entity를 그대로 사용한다. account 요청 시,응답으로 아래와 같이 json을 전송한다.

{
  "id": "1234",
  "name": "journiyoon",
  "email": "journiyoon@gmail.com",
  "contact": "010-1234-9090"
}

문제는, 데이터베이스를 변경할 때 발생한다.

"could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet"

예를 들어, contact 를 phone 으로 변경했다. entity는 아래와 같이 변경될 것이다.

  @Column(name = "phone")
  String phone;

서버를 변경 후 실행 시, 클라이언트에서는 조회 오류가 발생한다. 왜냐하면, json이 아래와 같이 전송되기 때문이다.

{
  "id": "1234",
  "name": "journiyoon",
  "email": "journiyoon@gmail.com",
  "phone": "010-1234-9090"
}

이제 클라이언트는 contact 데이터를 알 수 없다. entity를 변경했더니, 클라이언트까지 코드를 변경해야 하는 귀찮은 일이 발생했다. 혼자 구현하는 서비스라면, 뚝딱뚝딱 귀찮아도 고칠 수 있다. 하지만 수십개의 entity가 변경된다면 일일이 클라이언트에 전달해도 누락되는 부분이 발생할 수 있다. 바로 장애로 이어질 수 있는 부분이다. 따라서, DTO를 사용해야 함을 깨달았다.

DTO 사용이유 (검색으로 조금 더 보충하기)

  1. 데이터 전송 및 API 디자인: API 디자인 관점에서 DTO는 클라이언트에 제공되는 데이터를 커스터마이징하고 제한할 수 있다.
  2. 보안 및 데이터 노출: entity는 종종 DB 전체 데이터를 포함하며, 일부는 클라이언트에 노출되어서는 안될 수 있다. DTO를 사용함으로서 필요한 데이터만 전달하여 데이터 노출을 관리할 수 있다.
  3. 클라이언트와 서버 간 결합도 감소: entity 구조 변경 시 클라이언트에 미치는 영향을 최소화할 수 있다.
  4. 중첩 및 관련 데이터 관리: DTO를 사용하여 entity와 연결된 여러 데이터 속성을 단일 객체로 묶거나 중첩하여 관리할 수 있다.
  5. API 버전 관리: API 업데이트 시, entity 구조를 변경하지 않고 DTO 를 조정하여 API 버전 관리를 용이하게 할 수 있다.

Updated: