728x90

데이터를 믿고 쓰기 위해서는 `Validation`이 필요합니다.
Validation
- 유효성 검증
- 주로 사용자 또는 타 서버의 요청(Http Request) 내용에서 잘못된 내용이 있는지 확인하는 행위
Validation의 종류
학문적으로는 여러 세부적인 단계들도 있지만 실제로 개발자가 주로 챙겨야하는 검증은 크게 두 종류로 나뉩니다.
데이터 검증
- 데이터에 필수적인 데이터가 있는지 검증
- 문자열의 길이나 숫자형 데이터의 경우 값의 범위
- e-mail, 신용카드 번호 등 특정 형식에 맞춘 데이터
비즈니스 검증
- 서비스의 정책에 따라 데이터를 확인하여 검증
- 예) 배달 앱인 경우 배달 요청을 할 때 해당 주문건 이 결제 완료 상태인지 확인 등
- 경우에 따라 외부 API를 호출하거나 DB의 데이터까지 조회하여 검증하는 경우도 존재
Spring의 Validation
스프링은 웹만 사용되지 않기 때문에 웹 레이어에 종속적이지 않은 방법으로 벨리데이션 하려고 의도하고 있으며
주로 아래 두 가지 방법을 활용하여 벨리데이션을 진행합니다. (둘 다 데이터 검증에 가까움)
Java Bean Validation
JavaBean 기반으로 간편하게 개별 데이터를 검증합니다.
요즘에 가장 많이 활용되는 방법 중 하나이며
아래 코드처럼 JavaBean 내에 어노테이션으로 검증 방법을 명시합니다.
public class MemberCreationRequest {
@NotBlank(message="이름을 입력해주세요.")
@Size(max=64, message="이름의 최대 길이는 64자 입니다.")
private String name;
@Min(0, "나이는 0보다 커야 합니다.")
private int age;
@Email("이메일 형식이 잘못되었습니다.")
private int email;
// the usual getters and setters...
}
위처럼 요청 dto에 어노테이션으로 명시 후 아래처럼 @Valid 어노테이션을 해당 @RequestBody에 달게 되면
Java Bean Validation을 수행한 후 문제가 없을 때만 메서드 내부로 진입이 됩니다.
- 검증 중 실패가 발생하면 MethodArgumentNotValidException이 발생
@PostMapping(value = "/member")
public MemberCreationResponse createMember (
@Valid @RequestBody final MemberCreationRequest memberCreationRequest) {
// member creation logics here...
}
Spring Validator 인터페이스 구현을 통한 validation
public class Person {
private String name;
private int age;
// the usual getters and setters...
}
위처럼 Person이라는 JavaBean 객체가 있을 때 아래는 해당 인스턴스에서만 활용되는 validator입니다.
인터페이스에 있는 두 개의 메서드는 아래와 같은 역할을 합니다.
- supports: 이 validator가 동작할 조건을 정의, 주로 class의 타입을 비교합니다.
- validate: 원하는 검증을 진행합니다.
public class PersonValidator implements Validator {
/**
* This Validator validates only Person instances
*/
public boolean supports(Class clazz) {
return Person.class.equals(clazz);
}
public void validate(Object obj, Errors e) {
ValidationUtils.rejectIfEmpty(e, "name", "name.empty");
Person p = (Person) obj;
if (p.getAge() < 0) {
e.rejectValue("age", "negativevalue");
} else if (p.getAge() > 110) {
e.rejectValue("age", "too.darn.old");
}
}
}
Validation 수행 시 주의사항 및 패턴
주의사항
validation이 너무 여러 곳에 흩어져 있으면 테스트 및 유지 보수성이 떨어집니다.
- 중복된 검증: 정책 변경 시에 모든 중복 코드를 수정해야 할 수 있습니다.
- 다른 검증: 여러 곳에서 다른 정책을 따르는 검증이 수행될 수 있습니다.
가능한 validation은 로직 초기에 수행 후 실패 시에는 exception을 던지는 것이 처리가 편리합니다.
실무 활용 패턴
주로 사용되는 패턴
- 요청 DTO에서 Java Bean Validation으로 단순 데이터(유무, 범위, 형식 등)을 1차로 검증
- 로직 초기에 2차로 비즈니스 검증 수행 후 실패 시에는 Custom Exception(ErrorCode, ErrorMessage 를 입력)해서
예외를 던지도록 하고 예외 처리하여 응답을 생성합니다.
Spring validator의 장점
- Java Bean Validation에 비해 조금 더 복잡한 검증이 가능합니다.
Spring validator의 단점
- Validation을 수행하는 코드를 찾기가 상당히 어렵습니다.
- 완전히 데이터만 검증하는 것이 아니기 때문에 일부 비즈니스적인 검증이 사용되는 경우가 있습니다.
이 경우 비즈니스 검증 로직이 여러 곳으로 흩어지기 때문에 잘못된 검증(중복 검증, 다른 정책을 따르는 검증) 등
을 수행할 확률이 높아집니다.
이러한 검증 방법이 정답은 아니며
팀 내에서 주로 사용하는 검증 패턴을 따르는 것이 좋습니다.
'Develop > Spring' 카테고리의 다른 글
(작성 중) Spring web.xml (0) | 2022.11.16 |
---|---|
Spring SpEL (0) | 2022.11.16 |
Spring DataBinding (0) | 2022.11.16 |
Spring AOP (0) | 2022.11.16 |
Spring Resource (0) | 2022.11.16 |