99클럽 21일차 TIL: Validation Group
2024. 4. 24. 17:23ㆍ개발 공부
728x90
반응형
#1. 오늘의 학습 키워드
자바 스프링 부트에서 Validation을 특정 Group에 대해서만 걸어주고 싶을 때
- 자바 스프링 부트에서 개발을 진행할 때, 만약 같은 DTO로 여러 API 를 대응했을 때, validation 의 규칙을 다르게 해야하면 어떻게 해야될까
- 전에 Loki 서버로 에러 로그를 전송해주는 LokiUtil 컴포넌트를 개발하였다.
- 해당 메서드로 프론트의 로그도 같이 전송해주려 API 를 개발하였는데,
- 이때 API는 아래의 두 종류가 되고, 두 API는 기본적으로 로그 형식은 같기에, DTO는 하나를 공유하고 있다
- 프론트의 에러 로그 전송 API
- 프론트의 화면 방문 추적 로그 전송 API
#2. 공부한 내용
- @NotBlank
- 해당 어노테이션은 Dto의 속성에 공백이면 안 된다는 validation 을 걸어주는 어노테이션이다
- 해당 어노테이션에 Groups 를 지정하여 특정 그룹에 대한 validation 인 것을 명시해줄 수 있다.
- 사실 해당 어노테이션으로 예시를 드는 거고, 다른 어노테이션들도 group 지정 가능하다.
- 각자 요건에 맞는 다른 어노테이션들을 걸을 때 아래 공식 문서를 참조하면 된다.
- https://javadoc.io/doc/jakarta.validation/jakarta.validation-api/latest/jakarta/validation/constraints/package-summary.html
//DTO 클래스 내 속성
@Schema(description = "오류내용")
@JsonProperty("errContent")
@NotBlank(groups = {ErrorLogValidation.class})
private String err_content;
@Schema(description = "화면번호")
@JsonProperty("screenId")
@NotBlank(groups = {ScreenLogValidation.class})
private String screen_id;
//...
- Group 지정
- 위에 코드를 보면 오류 내용 속성은 ErrorLogValidation 클래스 그룹을 지정해주었고, 화면 번호 속성은 ScreenLogValidation 클래스 그룹을 지정해주었다.
- 그러면 클래스 그룹은 어떻게 정의하면 될까
- 인터페이스 선언
- Default 인터페이스는 validation 어노테이션을 달아줄 때 따로 그룹을 지정하지 않을 때 지정되는 그룹이다.
//같은 DTO 클래스 내 코드
public interface ErrorLogValidation extends Default {
}
public interface ScreenLogValidation extends Default {
}
- Controller 단에서 validation
- 그럼 이제 DTO에서의 각 속성에 대한 validation 그룹핑 작업은 끝냈으니, API 호출 시 해당 속성에 대한 유효성 검증을 선언해주면 된다.
- 원래 DTO 외부에서 해당 DTO에 대한 validation 작업은 아래 두개의 어노테이션을 사용하면 된다.
- @Valid
- @Validated
- 여기서는 어떤 특정 그룹에 대한 유효성 검증만 할 것임을 명시해야 돼서, @Validated 을 쓴다.
//Controller 코드
//...
@PostMapping("/log/error")
@Operation(summary = "프론트 에러 로그 전송", tags = "로그")
public ResponseEntity<JsonResponse> postErrorLog(HttpServletRequest request,
@RequestBody
@Validated(LogDto.ErrorLogValidation.class) LogDto logDto) {
//service method 호출 코드
//...
}
@PostMapping("/log/screen")
@Operation(summary = "프론트 사용자 추적 로그 전송", tags = "로그")
public ResponseEntity<JsonResponse> postScreenLog(HttpServletRequest request,
@RequestBody
@Validated(LogDto.ScreenLogValidation.class) LogDto logDto) {
//service method 호출 코드
//...
}
//...
#3. 오늘의 회고
- 자바 스프링에서 제공해주는 Validation 관련 어노테이션은 서비스 코드를 효과적으로 줄여줄 수 있는 상당히 편의한 기능이다.
- 왜냐면 일반적으로 해당 기능 없이, 서비스 로직 내부에서 직접 request Body (payload) 에 대한 유효성 검증을 하면 아래와 같은 단점이 생긴다.
- 유효성 검증 코드가 집중되어있지 않고, 분산 되어 있기에, 유지보수가 힘들다
- 그리고 같은 유형의 payload 에 대한 유효성 검증 코드는 흡사하기에, 코드 중복이 불가피하다.
- 비즈니스 로직 코드와 유효성 검증 코드가 혼재 되어있어서, 코드의 가독성과 유지보수성이 저하된다.
- 위 단점을 극복할 수 있는 기능들의 장점을 극대화하려면, 기본적인 부분에서 그치기 보단 상술한 Validation Group 처럼 좀 더 디테일한 기능들을 파보는 것이 좋은 것 같다.
728x90
반응형
'개발 공부' 카테고리의 다른 글
99클럽 23일차 TIL: Thread (Java, Spring) (0) | 2024.04.26 |
---|---|
99클럽 22일차 TIL: KISS, YAGNI, DRY (2) | 2024.04.25 |
99클럽 20일차 TIL: SOLID (0) | 2024.04.23 |
99클럽 19일차 TIL: WebSocket (0) | 2024.04.22 |
99클럽 18일차 TIL: gRPC (0) | 2024.04.21 |