[Spring] DTO 사용 시 필요한 lombok annotation

Chooooo·2023년 9월 5일
1

TIL

목록 보기
15/28
post-thumbnail

요즘 프로젝트를 진행하면서 DTO에 작성하는 여러 개의 lombok 어노테이션의 사용 이류를 정확히 알지 못하고 사용하는 것 같아서 하나하나 알아보기로 했다.

😎 DTO

일단, DTO는 Data Transfer Object로 REST API 작성 시에 엔티티 대신에 DTO를 사용하여 Controller에서 데이터를 주고받는 용도로 사용한다. DTO를 사용하면 엔티티에 변질을 막을 수 있고, 로직에 맞춰 필요한 필드만 주고 받을 수 있어 DTO를 사용하는 것이 좋다 !

😉 Controller에서 DTO를 주고 받기 때문에 JSON 직렬화와 역직렬화가 일어난다.

  • 직렬화(serialization) : Java Object가 JSON으로 변환되는 것으로, ResponseBody를 사용할 때 일어난다. (서버 -> 클라이언트)

  • 역직렬화(deserialization) : JSON이 Java 오브젝트로 변환되는 것으로, RequestBody를 사용할 때 일어난다. (클라이언트 -> 서버)

😁 DTO 직렬화/역직렬화 시에 필드에 어떻게 접근 ?

Spring Boot에서 DTO를 직렬화/역직렬화 하기 위해서는 Jackson 라이브러리가 동작하는데, Jackson 내부에서는 ObjectMapper가 리플렉션(Java Reflection)을 사용한다.

  • 이 때 로직에서는 기본 생성자와 getter, setter가 필요하다.
  • 이전에는 무조건 필드에 값을 세팅해주기 위해서 setter를 사용해서 setter가 꼭 필요한 줄 알았다. 근데 그게 아니다.

🎈 직렬화(Java Object -> JSON) : getter 필요(setter 불가능), 기본 생성자 필요없음
🎈 역직렬화(JSON -> Java Object) : getter나 setter 중에 하나만 있어도 됨, 기본생성자 필요

🎈 DTO 역직렬화에서는 기본 생성자가 필요하다. 왜 ?

ObjectMapper의 동작 방식을 보면 역직렬화 시에 기본 생성자를 이용하여 객체를 생성한 후에 getter나 setter를 이용하여 필드를 가져온다. 이 때 필드를 가져오기 위해서는 위에서 말했던 reflection을 이용한다.

  • 그래서 setter가 필요하지 않은 이상 setter보다는 getter를 선언하는 것이 좋을 듯하다.(setter는 필드 값이 바뀔 가능성을 높여주기 때문)

🎈 이 때 DTO에서 기본 생성자의 접근 제한자 ?

위에서 말한 것처럼 DTO의 기본 생성자는 ObjectMapper의 내부 동장에서 리플렉션으로 사용된다.
결국 이 기본 생성자가 다른 용도로 외부에서 사용할 것이라면, 앞서 말한 리플렉션에서만 사용되기 때문에 private이어도 상관이 없다.

  • 오히려 불변성을 위해서 불필요한 객체 생성을 막기 위해서 private로 선언하는 것이 좋다 ?

😁 생성자 인자가 하나일 경우

  • 생성자가 하나일 경우에는 동작하지 않는다 !!
  • 이 때는 @JsonCreator를 꼭 사용
public class Dto {
	private final String name;
    
    @JsonCreator
    public User(String name) {
    	this.name = name;
    }
}

😉 엔티티 생성시에도 보통 @Entity, @NoArgsConstructor, @AllArgsConstructor, @Getter 이 정도는 필수로 선언한다.

DTO 관리

😊 DTO와 엔티티는 분리하고, 요청(Request), 응답(Response)은 따로 만드는게 좋다.

  • 모두가 행복하기 위해서는 세 가지(엔티티 + 최소 2종의 DTO)가 필요하다.

    • Entity(Member) : 데이터가 저장되는 클래스
    • EntityDtoRequest(MemberDtoRequest) : Post 요청 시 받아야 하는 데이터
    • EntityDtoResponse(MemberDtoResponse) : Get 요청 시 응답해줘야 하는 데이터
  • 굳이 추가해야 된다면 !

    • EntityDtoResponseSimple : 최소 정보만 전달해주는 심플 응답
    • EntityDtoResponseDetail : 모든 데이터를 전달해주는 디테일 응답

내용 더 정리해야함,

profile
back-end, 지속 성장 가능한 개발자를 향하여

0개의 댓글