[스프링] 왜 DTO를 사용해야 하는가?

peeerr·2023년 2월 24일
0

Spring

목록 보기
1/10
post-thumbnail

📌 Entity란?

엔티티는 DB에 직접적으로 매핑되는 클래스이다. 데이터베이스에 실제로 쓰일 필드를 정의하고 엔티티끼리 연관관계를 맺어주는 역할을 한다.

스프링을 처음 다뤄볼 때는 그냥 이 엔티티 클래스로 Request, Response 요청을 다 처리해주었다. 전에 축제 사이트를 개발할 때에도 이렇게 했다.

하지만 나중에 가서 보니 이렇게 엔티티로 처리하는 것은 매우 위험한 방식이며, 무조건 DTO를 사용해야 됐었다.

왜 엔티티 클래스로 처리하지 않고 굳이 귀찮게 DTO를 또 만들어서 처리하는 걸까?


📌 DTO란?

DTO란 Data Transfer Object의 약자이며, 클라이언트의 요청을 담아 전달하거나 서버의 응답을 담아 전달하는 역할을 한다.

엔티티 클래스로 요청, 응답을 처리하면 안되고 이 DTO로 처리해야 한다.

그렇다면 왜 이 DTO를 사용해야 하는 것일까?

📌 DTO를 사용하는 이유

  • 엔티티 클래스는 DB와 직접적으로 맞닿아 있는 클래스이다. 때문에 매우 조심히 다루어야 한다.

    • 컨트롤러의 요청, 응답 또는 타임리프 같은 템플릿 엔진에서 사용하게 되면, 데이터 값을 변경하는 일이 많아 테이블 컬럼 자체가 변경될 우려가 존재한다.
  • 엔티티 클래스가 요청/응답 객체와 항상 같지 않다.

예를 들어 회원 엔티티 클래스가 있다고 가정해 보자.

@Entity
public class Member {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(unique = true)
    private String username;

    private String password;

    @Column(unique = true)
    private String email;

}
  • 로그인 요청을 할 때 엔티티로 데이터를 받게 된다면
    • username과 password만 필요한데, 불필요한 필드가 존재한다.

@RequestParam 을 사용하면 필드 하나하나 입력 받을 수 있지만 그냥 객체 하나로 요청받는 것이 더 깔끔하다.

이럴 때는 다음과 같은 DTO를 사용해 데이터를 받아야 한다.

@Getter
@Setter
public class MemberRequest {

    private String username;

    private String password;

}

추가적으로 회원가입 할 때도 생각해 보자.
비밀번호 재확인을 하는 필드가 추가적으로 필요할 것이다.

스프링 시큐리티를 사용하면 데이터를 받을 클래스가 따로 필요 없이 편리하게 처리가 가능하다.


📌 DTO <-> Entity 간 변환

DB에 값을 반영하려면 요청 받은 DTO를 Entity로 변환해 주어야 하고 반대로 응답을 할 때 Entity를 DTO로 변환해 보내야 한다.

그럼 이 단계는 어디서 이루어지는 것이 좋을까?

여러 가지 방식이 있지만 다음 두 가지 방식을 보자.

첫 번째 방법

컨트롤러 계층에서 처리

  1. 컨트롤러에서 DTO로 요청받아 Entity로 변환하고 서비스에 넘겨준다.

  2. 서비스단에서는 특정 작업을 진행 한 후 다시 컨트롤러에 넘겨준다.

  3. 넘겨받은 Entity를 다시 DTO로 변환해 응답한다.

    장점

  • 서비스 계층은 DTO를 의존하지 않고 Entity에만 의존하기 때문에 재사용성이 높아진다.
    • 특정 DTO에 의존하게 된다면 오직 그 DTO만을 처리할 수 있는 로직이므로 재사용성이 낮아진다.

    단점

  • DTO가 Entity의 모든 데이터를 가지고 있는 것이 아니기 때문에 컨트롤러에서 Entity로 변환하기 어렵다.
    • 위의 회원 엔티티를 보면 회원 각각을 구분하기 위한 pk값인 id가 존재한다. Entity 변환 과정에서 이 id 값이 부여되지 않은 상태이다.

두 번째 방법

서비스 계층에서 처리

  1. 컨트롤러에서 DTO로 요청받아 그대로 서비스에 넘겨준다.

  2. 서비스단에서 특정 작업을 진행한 후 다시 DTO로 변환해 컨트롤러로 넘겨준다.

  3. 넘겨받은 DTO로 응답한다.

    장점

  • 컨트롤러 계층에서는 DTO에만 의존하기 때문에 Entity를 알지 못한다.
    • Entity를 더 안전하게 보호할 수 있다.

    단점

  • 위에 작성했듯이 특정 DTO에 의존하므로 재사용성이 낮아진다.
profile
개발 공부

0개의 댓글