📦 DTO란?

정의

DTO(Data Transfer Object)는 계층 간 데이터를 전달하기 위해 사용하는 객체이다. 특히 API 요청과 응답처럼 표현용 데이터를 분리해서 다룰 때 유용하다.

DTO는 Entity와 분리해서 사용하며, 필요한 데이터만 담는 용도로 설계한다.

🎯 DTO의 주요 목적

  • 계층 간 데이터 전달을 명확하게 구분한다.
  • Entity에 종속되지 않는 표현 전용 구조를 만든다.
  • API 응답에서 불필요한 정보를 노출하지 않는다.
  • 요청과 응답 형태를 화면이나 API에 맞게 유연하게 조정한다.

🧩 DTO와 Entity의 차이점

항목 Entity DTO
목적 DB 테이블과 매핑 데이터 전달
포함 정보 도메인 전체 데이터 필요한 데이터만
위치 영속성 계층과 밀접 Controller, Service 경계
책임 비즈니스 로직과 상태 표현 전달과 표현 중심

구분 포인트

Entity는 저장에 가깝고, DTO는 전달에 가깝다. 둘을 섞으면 구조는 편해 보일 수 있지만, 유지보수성이 떨어질 수 있다.

🧷 주요 어노테이션 비교

어노테이션 전달 방식 주 사용 용도 DTO 바인딩 Bean Validation 적용
@RequestParam 쿼리 파라미터, 폼 데이터 단일 값, 간단한 입력 ✅ (@Validated와 함께 사용)
@RequestBody JSON 등 HTTP Body 복잡한 JSON 구조
@ModelAttribute 쿼리 파라미터, 폼 데이터 폼 전체 객체 바인딩

✍️ 사용 예시

@RequestParam 예시

@GetMapping("/search")
public String search(@RequestParam String keyword) {
    return "검색어: " + keyword;
}

@RequestBody 예시

@PostMapping("/users")
public ResponseEntity<String> createUser(@RequestBody @Valid UserRequest request) {
    return ResponseEntity.ok("사용자 등록 완료: " + request.getName());
}

@ModelAttribute 예시

@PostMapping("/form")
public String submitForm(@ModelAttribute UserForm userForm) {
    return "제출 완료: " + userForm.getName();
}

🧱 DTO 사용 예제

1️⃣ DTO 클래스 정의

public class UserResponseDTO {
    private String name;
    private String email;

    public UserResponseDTO(String name, String email) {
        this.name = name;
        this.email = email;
    }

    // getter, setter 생략
}

2️⃣ Entity → DTO 변환 예시

User user = userRepository.findById(1L).orElseThrow();
UserResponseDTO dto = new UserResponseDTO(user.getName(), user.getEmail());

활용

DTO는 조회 결과를 그대로 내보내기보다 응답 전용 형태로 가공할 때 특히 유용하다.

🛠️ DTO 자동 매핑 도구

라이브러리 특징
ModelMapper 필드 이름 기반 자동 매핑
MapStruct 컴파일 타임 매핑, 성능 우수
Orika 속도와 유연성을 함께 제공

[!important] 선택 기준 단순함이 필요하면 ModelMapper, 성능과 명확성이 중요하면 MapStruct를 고려한다.

✅ 장점과 단점

장점

  • 도메인 모델과 API 응답 구조를 분리할 수 있다.
  • 불필요한 정보 노출을 줄일 수 있다.
  • View 또는 API에 맞는 형태로 쉽게 가공할 수 있다.
  • 요청 DTO와 응답 DTO를 나눠서 더 명확하게 설계할 수 있다.

단점

  • DTO 클래스가 많아지면 관리 비용이 늘어난다.
  • Entity와 DTO 사이 변환 로직이 필요하다.
  • 작은 프로젝트에서는 오히려 코드가 늘어나 보일 수 있다.

연결문서

댓글남기기