DTO 필드로 Enum 타입을 두는 것은?

Jeong_Hyun·2025년 5월 19일
0

DTO는 데이터 전송을 위해 설계된 객체로, 데이터를 단순하고 명확하게 전달하는 것을 목적으로 합니다. 불필요한 로직이나 비즈니스 규칙은 포함하지 않는 것이 이상적입니다.

  • DTO 필드로 Enum 타입을 두는 것은 도메인과 DTO의 결합도를 높입니다.
    예를 들면, Enum 값을 추가하거나 변경하면 DTO 쪽도 수정을 해줘야 하는 상황이 발생한다.

  • Enum 타입을 JSON으로 직렬화시켜야 하기에 클라이언트와의 데이터 통신이 원활하지 않게 됩니다.

String 타입을 사용하고 Custom Validation을 만들어 검증을 해주자.

Custom Validation

@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = ValidEnumValidator.class)
public @interface ValidEnum {
    String message() default "값이 유효하지 않습니다.";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};

    // 검증할 Enum 클래스를 지정하는 속성
    Class<? extends Enum<?>> enumClass();
}

ValidEnumValidator 구현체

public class ValidEnumValidator implements ConstraintValidator<ValidEnum, String> {
    private Set<String> enumValues;

    @Override
    public void initialize(ValidEnum annotation) {
        // Enum 클래스에서 모든 값의 이름을 가져와 Set으로 저장
        enumValues = Arrays.stream(annotation.enumClass().getEnumConstants())
                           .map(Enum::name)
                           .collect(Collectors.toSet());
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        // 필드가 null이거나 비어 있을 경우 유효성을 true로 반환
        if (value == null || value.isEmpty()) {
            return true;
        }
        // 필드의 값이 Enum 값들에 포함되어 있는지 확인
        return enumValues.contains(value);
    }
}

DTO

@ValidEnum(enumClass = OrderStatus.class, message = "주문 상태가 유효하지 않습니다. 다시 시도해 주세요.")
private final String orderStatus;

https://easy-stack.tistory.com/entry/Spring-DTO-설계-시-Enum-타입을-피해야-하는-이유

0개의 댓글