카카오 쇼핑몰 클론코딩을 진행하며 주문하기 기능을 구현하던 도중, POSTMAN을 활용해 "localhost:8080/orders/1"를 요청 했는데, 아래와 같은 오류가 발생했다.

오류 코드를 보며 내가 알 수 있는건 DTO쪽의 문제라는 것과 직렬화와 관련된 문제라는 것이였다. 내가 건든 코드는 OrderService, OrderController, OrderResponse 였고, 모든 코드를 확인을 해봤지만 어디가 문제인지 못찾겠어서 결국 멘토님께 SOS를 했다!
결론은, DTO 직렬화 문제로 @GETTER가 없어서 발생한 오류였다.
진짜 코드를 다시 살펴보니 OrderResponse에서 SaveDTO 앞에 @Getter를 선언하지 않았고, 넣어주니 잘 실행되었다.

그냥 항상 DTO를 작성할 때는 @Getter과 @Setter를 무의식적으로 넣었던게 이렇게 화를 불러일으켰다..🥹
그래서 다시 DTO와 Getter, Setter의 개념을 정리해볼까 한다.
DTO (Data Transfer Object, 데이터 전송 객체)는 프로세스 사이에서 데이터를 이동하기 위한 객체로 중요한 정보를 노출시키지 않고 두 시스템 간 통신을 원할하게 할 수 있다.

Request DTO : 서버에서 수신
Response DTO : 서버에서 반환

DTO는 계층간 데이터 교환이 이루어질 수 있도록 하는 객체로 특별한 로직을 가지지 않는 순수한 데이터 객체이다
또한, 굳이 Setter를 이용해 값을 수정할 필요 없이, 생성자를 이용해 값을 할당한다.
DTO는 SPRING에 의해 자동으로 직렬화/ 역직렬화 된다.
두 어노테이션은 모두 Lombok이 제공하는 것으로, 클래스 내의 멤버 변수에 대한 Getter와 Setter 메서드들을 자동으로 생성해준다.
public class Person {
private String name;
public String getName() {
return name;
}
}
public class Person {
private String name;
public void setName(String name) {
this.name = name;
}
}
➕ Getter와 Setter를 사용하는 이유는, 데이터를 보호하기 위함이다.
데이터를 불러올 때 한번 더 가공하는 과정을 거쳐 내부 데이터가 결함을 가지지 않도록 하는 것 이다.(무결성) 그러나 무분별한 Setter은 데이터 무결성을 해칠 수 있다. (setter로 데이터를 수정하면, 어떤 부분을 수정하는제, 어디서 데이터를 수정하는지 알 수 없다) 그래서 이를 해결하기 위해 객체를 생성하는 생성자와, 이를 표현하는 메소드를 분리하여 사용하는 Builder 패턴을 이용해서 데이터 조금 더 직관적인 코드를 작성할 수 있다.
Spring에서 Controller 계층과 Service 계층 사이의 데이터 전송을 위해 DTO를 사용한다.
요청에 따른 응답을 반환할 때 DTO 객체를 다른 데이터 형식으로 변환시켜줘야 하는데, Spring은 Jackson 라이브러리를 사용하여 Json 데이터들을 직렬화 / 역직렬화 작업을 진행한다. (DTO <-> Json)
이처럼 Spring에서 개발자 대신 데이터 변환을 해주기 위해 ResponseDto의 데이터 호출하게 되고, 이를 위해 getter 메소드가 필요하다.
대부분의 필드는 private로 사용하여 접근을 막는다.
그래서 외부에서 사용하기 위해서는 getter가 필요하다.
잘 읽었습니다. 좋은 정보 감사드립니다.