이 글은 프로젝트를 만들던 중 DTO를 모든 요청이나 응답마다 DTO를 만들어야 할까? 에 대한 의문에 DTO의 여러 글들을 찾아보니 개인마다 차이가 꽤 있는 것 같아 내 방식을 정리하고자 쓰는 글이다.
문제1. DTO는 요청이나 응답마다 전부 만들어야 할까?
문제2. DTO를 entity로 어떻게 변환해야 할까?
문제3. builder를 쓸까? @AllArgsConstructor를 써야할까?
결론부터 말하자면 웬만하면 요청이나 응답마다 DTO를 생성하는 것으로 결론이 났다.
어떤 경우에는 값이 null이고 어떤 경우에는 값이 있으면 모호해지기 때문에 유지보수가 어려워진다고 한다.
@Getter
@AllArgsConstructor
public class MemberCreateDTO {
private String username;
private String password;
}
@Getter
@AllArgsConstructor
public class MemberUpdateDTO {
private String username;
private String password;
}
값이 중복되긴 하지만 후에 잘못해서 생기는 유지비용보다는 오히려 저렴한 비용이라고 하기 때문에 요청이나 응답마다 전부 생성하기로 했다.
예전에는 생성자를 사용해서
MemberResponseDTO memberResponseDTO = new MemberResponseDTO("username", "password");
이런식으로 만들었지만 MemberDTO.response의 코드가 바뀌면 이 코드도 직접 바꿔야 한다는 문제가 있다.
이 문제를 해결하기 위한 방법은 Mapper를 사용하는 것이다.
DTO 클래스와 엔티티를 서로 변환해주는 것이다.
Mapper를 DTO 내부에 구현해서 벼경될 때 마다 사용하는 방법이 있지만 속도가 빠른 외부 라이브러리를 사용하면 편하다.
빠른 라이브러리로는 https://github.com/arey/java-object-mapper-benchmark 가 있는데, 사용법 등은 내가 참고한 사이트를 보면 될 것 같다.
Mapper https://its-ward.tistory.com/entry/Spring-DTO%EC%99%80-Mapper
이것도 builder를 쓰는게 좋다, setter를 쓰는게 좋다, 등등 여러 말들이 있어서 부족한 지식으로 한번 말해보자면
setter는 예기치 못한 곳에서 값을 잘못 바꿀 수 있다고 생각하여 setter 보다는 생성자나 builder를 사용하는게 좋아보이는데 생성자 보다는 builder가 더 좋을 것 같다.
이유는 생성자는 지정된 순서대로 값을 넣어야 하기 때문에 동일 타입의 순서를 잘못 넣었을 경우 컴파일러에서는 오류를 찾을 수 없기 때문이다.
이 글을 쓰면서 배워야 할 것이 많다는 것을 다시한번 느낄 수 있어서 재미있었다
김영한님 DTO 답변 : https://www.inflearn.com/questions/72423/dto
Controller에서 Service에 값은 전달하는 방법 : https://kafcamus.tistory.com/12 (한번씩 읽어보면 좋을 것 같다)