본문 바로가기

[기획 & PM & BE] BE:OUR 프로젝트

[BE:OUR] RequestDto, ResponseDto 필요한 어노테이션과 직렬화를 위한 @Getter

Q. 아래 코드(Dto 코드)들에 @Getter, @Setter, 생성자 어노테이션에 대해 리뷰하고 있습니다. 제 생각에는 RequestDto에는 @Getter만 필요한 것 같고, ResponseDto에는 생성자 어노테이션만 필요할 것 같은데 그래도 될까요?

 

 

A.

✅ 결론부터 말씀드리면:

✔️ RequestDto는 @Getter만 있으면 충분합니다.

  • @Setter는 필요하지 않으며, 생성자도 명시할 필요 없습니다.

✔️ ResponseDto는 @Getter + @AllArgsConstructor만 있으면 충분합니다.

  • DTO를 불변(immutable)하게 유지하고, 명확한 객체 생성을 유도할 수 있습니다.
  • @Setter는 되도록 사용하지 않는 것이 좋습니다.

 

🔍 이유와 각 클래스별 코드 리뷰

📌 FindLoginIdRequestDto

@Getter
public class FindLoginIdRequestDto {
  @NotBlank private String name;
  @NotBlank @Email private String email;
  @NotBlank @Pattern(...) private String phone;
}
  • ✅ @Getter: 컨트롤러에서 서비스로 전달할 때 getter로 값 꺼냄 → 필요함.
  • ❌ @Setter: DTO를 수정할 일 없음 → 불필요.
  • ❌ 생성자: JSON → 객체 매핑(Jackson)이 기본 생성자 + setter or field에 직접 주입하는 방식 사용 → 필요 없음.

 

📌 FindLoginIdResponseDto

@Getter
@AllArgsConstructor
public class FindLoginIdResponseDto {
  private String loginId;
}
  • ✅ @Getter: 응답에서 값을 직렬화할 때 사용됨 → 필요.
  • ✅ @AllArgsConstructor: 응답 생성 시 new로 직접 생성함 → 필요.
  • ❌ @Setter: 응답 객체는 불변이어야 하므로 setter 불필요.

 

📌 ResetPasswordRequestDto

@Getter
@Setter // ❗이건 제거 추천
public class ResetPasswordRequestDto {
  @NotBlank private String loginId;
  ...
}
  • ✅ @Getter: 필요.
  • ❌ @Setter: JSON → 객체 매핑은 기본 생성자 + 필드 주입 또는 @Getter만으로도 충분.
    • 보안상 패스워드 관련 DTO에 setter는 특히 피하는 것이 좋습니다.

setter를 제거하고, 필요 시 생성자를 직접 만들거나 Builder 패턴을 고려하는 것이 더 안전하고 유지보수에 좋습니다.

 

📌 ResetPasswordResponseDto

@Getter
@Setter // ❌ 제거 추천
@AllArgsConstructor
public class ResetPasswordResponseDto {
  private String tempPassword;
}
  • ✅ @Getter: 직렬화에 필요.
  • ✅ @AllArgsConstructor: 객체 생성에 필요.
  • ❌ @Setter: 응답 객체를 외부에서 수정하지 않도록 제한하는 것이 좋습니다.

 

💡 정리: DTO 어노테이션 정리표

DTO 유형 @Getter @Setter 생성자 어노테이션 (예: @AllArgsConstructor)

Request DTO ✅ 필요 ❌ 지양 ❌ 필요 없음 (기본 생성자 + @Getter suffice)
Response DTO ✅ 필요 ❌ 지양 ✅ 필요 (@AllArgsConstructor 등)

 

✨ 추가 팁

  • Setter 남용은 객체를 예측 불가능하게 만들 수 있어 유지보수에 해롭습니다.
  • DTO는 최대한 불변성(immutable) 을 유지하는 방향으로 설계하는 것이 좋습니다.
  • Jackson은 @Getter만 있어도 정상적으로 JSON 직렬화/역직렬화를 처리할 수 있습니다.

 

 


Q. '✅ @Getter: 응답에서 값을 직렬화할 때 사용됨 → 필요.'에서 직렬화가 뭔가요?

 

 

A. 직렬화(Serialization)는 백엔드 개발에서 자주 나오는 중요한 개념입니다.

 

직렬화란?

객체(Object)를 저장하거나 전송할 수 있는 형태(주로 문자열)로 바꾸는 과정을 말합니다.

  • Java에서의 객체는 메모리 위에 존재하는 복잡한 자료구조예요.
  • 이걸 JSON, XML, 바이트 배열 같은 형태로 바꿔야 다른 시스템(예: 웹 브라우저, 네트워크, 파일 저장 등)에 보내거나 저장할 수 있습니다.

→ 이 **변환 과정이 직렬화(Serialization)**입니다.

 

✅ 예시로 보는 직렬화

예를 들어 이런 Java 객체가 있다고 해볼게요:

@Getter
@AllArgsConstructor
public class FindLoginIdResponseDto {
  private String loginId;
}
new FindLoginIdResponseDto("hello123");

이걸 브라우저에게 JSON으로 응답하려면 내부적으로 이런 문자열로 직렬화됩니다:

{
  "loginId": "hello123"
}

 

 

🔁 반대로, 역직렬화(Deserialization)도 있어요!

클라이언트가 이런 JSON을 백엔드에 보낼 수 있겠죠:

{
  "loginId": "hello123"
}

이걸 서버에서는 다시 Java 객체로 변환해야 합니다.
이 과정을 **역직렬화(Deserialization)**라고 합니다.

 

💡 @Getter가 직렬화에 필요한 이유?

Jackson 같은 JSON 변환 라이브러리는 내부적으로 Java 객체에서 값을 꺼내 JSON을 만들기 위해 Getter 메서드를 사용합니다.

예: getLoginId() → "loginId": "값" 형태로 JSON 구성

 

✅ 정리

용어 의미

직렬화 객체 → JSON (or 다른 포맷) 변환
역직렬화 JSON (or 다른 포맷) → 객체 변환
@Getter 직렬화할 때 Jackson이 객체의 값을 꺼낼 수 있도록 도와줌