DTO(Data Transfer Object)란 계층간 데이터 교환을 위해 사용하는 객체이다. 아샬님은 DTO 에 대해 제대로 된 객체라고 할 수는 없고 그냥 Java Bean 이라고 하셨다. 그런데 DTO 와 엔티티는 같은 것 아닌가? 왜 DTO 로 굳이 변환을 해야 할까?
DTO 를 알기 위해서는 먼저 MVC 패턴에 대해 알아야 한다.
MVC 패턴(Model-View-Controller Pattern)은 애플리케이션 개발시 그 구성요소를 Model과 View, Controller 세 가지 역할로 구분하는 디자인 패턴이다. 비즈니스 처리 로직(Model)과 UI 영역(View)의 중간에서 Controller가 연결해주는 역할을 한다.
Controller는 View로부터 들어온 사용자 요청을 해석해 Model을 업데이트하거나 Model로부터 데이터를 받아 View로 전달하는 작업 등을 수행한다. Controller는 View와 도메인 Model의 데이터를 주고 받을 때 별도의 DTO를 주로 사용한다. 도메인 객체를 View에 직접 전달할 수 있지만, 도메인의 비즈니스 기능이 노출될 수 있으며 Model과 View 사이에 의존성이 생기기 때문이다. 그래서 우리는 DTO라는 비지니스로직을 빼고 뷰에 필요한 별도의 데이터 객체를 만들어 뷰에 전달해준다. 그래서 도메인 객체를 관리해주는 리포지토리와 리포지토리에 있는 도메인 객체를 서비스에서 DTO 객체로 변환시켜 뷰로 전달하는 것이다.
<DTO 를 사용하지 않으면 발생할 수 있는 문제점>
<User.java>
public class User {
private Long id;
private Sting name;
private String email;
private String password;
...
}
<UserController.java>
@GetMapping("/posts/{id}")
@ResponseStatus(HttpStatus.OK)
public User viewMyPage(@PathVariable("id") Long id) {
return userService.viewMyPage(id);
}
이렇게 Controller가 클라이언트의 요청에 대한 응답으로 도메인 Model인 User를 넘겨주면 다음와 같은 문제점이 있다.
- 도메인 Model의 모든 속성이 외부에 노출된다.
- 위 예시의 경우 사용자가 마이페이지 조회에 대한 요청을 하는데 그에 대한 응답으로 User 타입을 사용해서 외부에 노출되면 안되는 'password' 데이터까지 응답해준다. 이처럼 도메인 Model 자체를 응답해주면 중요한 정보가 외부에 노출되는 보안 문제가 발생한다.
- 또한 View에서 보낸 요청에 대한 데이터 외의 불필요한 데이터 (name, email, password) 를 모두 가지고 있다.
- UI 계층에서 Model의 메소드를 호출하거나 상태를 변경시킬 위험이 존재한다.
- Controller 와 Service 사이에 강한 의존성이 생길 수 있다. Service 가 받고 싶은 파라미터가 Controller 에게 종속적이게 되면, Service 가 Controller 패키지에게 의존하게 된다. 따라서 이를 방지하기 위해 Service 가 원하는 포맷에 맞춰 Controller 단에서 DTO 를 통해 그 포맷을 맞춰준다.
- Model과 View가 강하게 결합되어, View의 요구사항 변화가 Model에 영향을 끼치기 쉬워진다.
- 또한 User Entity의 속성이 변경되면, View가 전달받을 JSON 등 클라이언트의 코드에도 변경을 유발하기 때문에 상호간 강하게 결합된다.
DTO 의 사용 목적에 대해서는 인지했는데, 여러 정보를 찾아보니 DTO 를 담당하는 것은 서비스인 것인지 컨트롤러인것인지, 어느 영역에서 어느 정도로 사용해야 하는 것인지에 대한 문제가 뜨거운 감자인 것 같다. 안정적으로 보이는 방법은 컨트롤러에서 DTO 를 생성해서 서비스에게 넘겨주는 것 같은데 이건 조금 더 알아보아야 할 것 같다.
참고:
[Spring boot] DTO의 사용 범위
DTO의 변환은 어디서 일어나야 하는 걸까?
velog.io
'TIL' 카테고리의 다른 글
Java Arrays 클래스 (22.10.24 TIL) (0) | 2022.10.24 |
---|---|
JPA (Java Persistence API) (22.10.23 TIL) (0) | 2022.10.23 |
소프트 스킬의 중요성 (22.10.21 TIL) (0) | 2022.10.21 |
잡념 없애기 (22.10.20 TIL) (1) | 2022.10.20 |
코드에 의도 드러내기 (22.10.19 TIL) (1) | 2022.10.19 |
댓글