💡 개요
Spring에서 값 검증에 자주 사용되는 @Valid는 어떨 때 사용하는 것일까?
📕 @Valid
난 보통 DDD 패턴에서 엔티티의 Value Object를 사용하기 때문에 해당 객체 내부에서 값 검증을 하는 경우가 많다.
하지만 Value Object는 주로 엔티티와 함께 사용되고, 데이터베이스에 접근하기 전 단계에서 활용된다.
이때 클라이언트의 요청은 Controller → Service → Repository 흐름으로 진행되는데, 만약 잘못된 값이 들어오면 최종적으로 Repository 단의 직전에 검증 오류가 발생한다.
서버 입장에서는 잘못된 데이터가 최대한 빨리 차단되는 것이 효율적이기 때문에, 가능한 앞단에서 검증을 수행하는 것이 좋다.
이때 사용하는 것이 @Valid 어노테이션이다.
🛠️ @Valid 사용 방법
다음은 컨트롤러에서 @Valid을 사용하는 코드이다.
@RestController
@RequestMapping("/members")
public class MemberController {
@PostMapping("/signup")
public String signUp(@Valid @RequestBody MemberSignUpRequest request) {
...
return "회원가입 완료";
}
}
class MemberSignUpRequest {
@NotNull(message = "이름은 필수 입력 항목입니다.")
private String name;
@NotNull(message = "이메일은 필수 입력 항목입니다.")
private String email;
...
}
회원 가입 시 name과 email이 null이면 예외가 발생하고, 오류 메시지가 반환된다.
다음은 입력된 정수의 값을 검증하는 코드이다.
@RestController
@RequestMapping("/products")
public class ProductController {
@PostMapping("/register")
public String register(@Valid @RequestBody ProductRequest request) {
...
return "제품 등록 완료";
}
}
class ProductRequest {
@Min(value = 1, message = "가격은 최소 1원 이상이어야 합니다.")
@Max(value = 1000000, message = "가격은 최대 1,000,000원 이하여야 합니다.")
private int price;
@Positive(message = "재고는 양수여야 합니다.")
private int stock;
@DecimalMin(value = "0.0", inclusive = false, message = "할인율은 0보다 커야 합니다.")
@DecimalMax(value = "1.0", message = "할인율은 1 이하이어야 합니다.")
private double discountRate;
...
}
제품 등록에 가격의 범위, 제품 재고 음수 제한, 할인률 제한을 설정했다.
- @Min, @Max: 최솟값과 최댓값 제한
- @Positive: 양수만 허용
- @DecimalMin, @DecimalMax: 실수 범위의 최소, 최대값 제한
이처럼 @Valid 어노테이션을 사용하면, 클라이언트의 잘못된 입력을 빠르게 차단하고, 서버의 안정성을 높일 수 있다.
만약 검증에 실패하면 MethodArgumentNotValidException 예외가 발생하므로, 공통 예외 처리에서 적절하게 다루면 된다.
'개발 일기' 카테고리의 다른 글
[개발 일기] 2025.03.21 - 외부에서의 주입이 테스트 코드에 용이한 이유 (0) | 2025.03.21 |
---|---|
[개발 일기] 2025.03.20 - 에러 로그를 찍어도 되나? (Feat : 시큐어 코딩) (0) | 2025.03.20 |
[개발 일기] 2025.03.18 - MultipartFile와 Setter의 관계 (0) | 2025.03.18 |
[개발 일기] 2025.03.17 - Code Kata (0) | 2025.03.17 |
[개발 일기] 2025.03.16 - Session.invalidate() (0) | 2025.03.16 |