요즘 프로젝트를 진행하면서 DTO에 작성하는 여러 개의 lombok 어노테이션의 사용 이류를 정확히 알지 못하고 사용하는 것 같아서 하나하나 알아보기로 했다.
일단, DTO는 Data Transfer Object
로 REST API 작성 시에 엔티티 대신에 DTO를 사용하여 Controller에서 데이터를 주고받는 용도로 사용한다. DTO를 사용하면 엔티티에 변질을 막을 수 있고, 로직에 맞춰 필요한 필드만 주고 받을 수 있어 DTO를 사용하는 것이 좋다 !
😉 Controller에서 DTO를 주고 받기 때문에 JSON 직렬화와 역직렬화가 일어난다.
직렬화(serialization)
: Java Object가 JSON으로 변환되는 것으로, ResponseBody를 사용할 때 일어난다. (서버 -> 클라이언트)
역직렬화(deserialization)
: JSON이 Java 오브젝트로 변환되는 것으로, RequestBody를 사용할 때 일어난다. (클라이언트 -> 서버)
Spring Boot에서 DTO를 직렬화/역직렬화 하기 위해서는 Jackson 라이브러리가 동작하는데, Jackson 내부에서는 ObjectMapper가 리플렉션(Java Reflection)을 사용한다.
🎈 직렬화(Java Object -> JSON) : getter 필요(setter 불가능), 기본 생성자 필요없음
🎈 역직렬화(JSON -> Java Object) : getter나 setter 중에 하나만 있어도 됨, 기본생성자 필요
ObjectMapper의 동작 방식을 보면 역직렬화 시에 기본 생성자를 이용하여 객체를 생성한 후에 getter나 setter를 이용하여 필드를 가져온다. 이 때 필드를 가져오기 위해서는 위에서 말했던 reflection을 이용한다.
위에서 말한 것처럼 DTO의 기본 생성자는 ObjectMapper의 내부 동장에서 리플렉션으로 사용된다.
결국 이 기본 생성자가 다른 용도로 외부에서 사용할 것이라면, 앞서 말한 리플렉션에서만 사용되기 때문에 private이어도 상관이 없다.
@JsonCreator
를 꼭 사용public class Dto {
private final String name;
@JsonCreator
public User(String name) {
this.name = name;
}
}
😉 엔티티 생성시에도 보통 @Entity, @NoArgsConstructor, @AllArgsConstructor, @Getter 이 정도는 필수로 선언한다.
😊 DTO와 엔티티는 분리하고, 요청(Request), 응답(Response)은 따로 만드는게 좋다.
모두가 행복하기 위해서는 세 가지(엔티티 + 최소 2종의 DTO)가 필요하다.
굳이 추가해야 된다면 !