Spring/아키텍처 (Architecture)

Entity와 DTO(Data Transfer Object)의 차이

가지코딩 2025. 5. 9. 11:34

개발을 하다 보면 한 가지 의문이 생긴다.

"Entity랑 DTO, 왜 굳이 나눠서 써야 하지?"

 

처음엔 둘 다 그냥 데이터를 담는 그릇처럼 보인다.

 

하지만, 이 두 객체는 그 목적과 사용되는 맥락이 다르기 때문에, 실제로는 각각 다른 역할을 수행한다.

이 글에서는 Entity와 DTO의 차이점을 명확히 구분하고, 왜 둘을 분리해서 사용하는 것이 중요한지에 대해 살펴보겠다.


1. Entity

"Entity는 데이터베이스 테이블과 1:1로 매핑되는 객체이다."

 

특징

  • @Entity로 선언되고, 주로 JPA 같은 ORM과 함께 사용된다.
  • DB에 직접 저장하거나 조회하는 객체다.
  • 비즈니스 도메인을 표현하기도 한다.
@Entity
public class User {
    @Id @GeneratedValue
    private Long id;
    private String username;
    private String email;

    // 생성자, getter, setter
}

2. DTO (Data Transfer Object)

"DTO는 데이터를 전송하기 위한 객체, 즉 계층 간 이동용 컨테이너이다."

 

특징

  • DB와는 무관하며, 계층 간 데이터 전달 또는 API 요청/응답에 사용된다.
  • 필요한 필드만 담고, 불필요한 정보는 과감히 생략한다.
  • 비즈니스 로직 없이, 순수 데이터 구조만 포함한다.
public class UserDTO {
    private String username;
    private String email;

    // 생성자, getter, setter
}

  

 

* 실무에서 DTO 용도

DTO 종류 용도 설명
요청 DTO 클라이언트 → 서버로 들어오는 요청 데이터 (@RequestBody 등)
응답 DTO 서버 → 클라이언트로 반환되는 응답 데이터 (보안, 구조 정제 필요)
내부 전달 DTO Controller ↔ Service 등 계층 간 데이터 이동

3. Entity를 직접 노출하면 안 되는 이유

예제

@GetMapping("/users")
public List<User> getUsers() {
    return userRepository.findAll(); // ❌ 지양
}

 

이렇게 Entity를 직접 노출하면...

  • 보안 이슈 (예: 비밀번호 노출)
  • 필드가 바뀌면 API 응답 구조가 깨짐
  • 순환 참조 문제 발생 (Lazy 로딩 등)

이러한 문제들이 발생할 수 있다.

 

 

Entity를 직접 반환하지 않고, DTO를 따로 만들어 응답 전용 구조로 바꿔주는 게 좋다.

@GetMapping("/users")
public List<UserDTO> getUsers() {
    return userService.getAllUsers().stream()
                      .map(user -> new UserDTO(user.getUsername(), user.getEmail()))
                      .collect(Collectors.toList());
}

4. Entity vs DTO 정리

항목 Entity DTO
목적 DB 테이블과 매핑 데이터 전달용 구조체
위치 Repository, Service 내부 Service ↔ Controller, 또는 API 응답 등
로직 포함 포함 가능 (비즈니스 메서드 등) 없음 (순수 데이터 전달)
민감 정보 포함될 수 있음 제외함
변경 영향도 DB에 영향 있음 없음 (자유롭게 구조 수정 가능)

 


5. 결론

Entity는 내부용, DTO는 외부용.

이 원칙 하나만 기억해도 설계가 훨씬 명확해진다.

 

  • Entity: DB와의 직접적인 연결고리
  • DTO: 계층 간, 또는 클라이언트와 통신하기 위한 데이터 계약서
    • 특히 DTO를 요청/응답 단위로 나눠서 설계하면, API 변경에 유연하고, 보안과 유지보수 측면에서도 훨씬 좋다.