Pull Request 내용
하 글쓰다가 날라가서 쓸 맛이 안난다 Issue / PR 내용만 복붙하고 어떻게 구현 했는지 써야겠다.
Issue 내용
요청에 대한 유효성 검사(Validation) 구현 #21
현재 Web 에서 API 로 향하는 요청에 대하여 Front-end 에서의 유효성 검사가 수행되고 있으나
Postman 등 다른 경로를 통해 들어온 요청에 대해서는 해당 유효성 검사를 거치지 않으므로
서버에서 별도의 Validation 을 수행하여 예기치 못한 오류가 발생하지 않도록 해야합니다.
(예를 들어 특정 좌표 및 반경을 기준으로 창고를 조회하는 api 에서 반경 값을 아주 큰 수로 지정하게 되면
DB에 저장된 모든 Storage 를 서버로 가져오게 되므로 아주 큰 부하를 야기할 수 있습니다.)
이는 java 에서 공식적으로 제공하는 표준 기술인 Bean validation 을 통해 구현할 수 있는데
javax.validation 패키지에 관련 클래스와 메서드가 정의 되어 있으며, 스프링 프레임 워크에서도
이를 연계하여 사용할 수 있도록 공식적으로 지원하고 있습니다.
상기 Bean Validation 기능을 이용하여 Controller 로 전달되는 DTO 에 대하여
일차적인 유효성 검사를 수행할 예정이며, 이후 추가적인 유효성 검사가 필요할 시
Controller 의 내부 로직 또는 Service 계층에서 수행할 것입니다.
Pull Request 내용
feat: Bean Validation 기능을 위한 Setup
Bean Validation Api 는 Request 에 담긴 데이터를 Dto 또는 파라미터에 맵핑하는 과정에서
맵핑 결과를 BindingResult 라는 객체로 저장합니다.
맵핑 과정에서 요청 데이터가 Dto 의 각 필드에 규정된 Constraint 에 위배되는 경우
MethodArgumentNotValidException 이라는 예외를 발생 시키는데
BindingResult 는 해당 Exception 에 저장됩니다.
GlobalExceptionHandler(CustomExceptionHandler 에서 변경) 에서 해당 예외를
Handler 하여 BindingResult 를 적절한 메세지와 함께 다시 반환하도록 하여
적절한 피드백이 이뤄지도록 구현하였습니다.
위 내용을 구현한 코드
1. 우선 api 의 인자에 @Valid 애너테이션을 붙인다 (javax.validation 패키지)
그러면 맵핑 결과를 Binding Result 객체에 담게 된다.
BindingResult 에는 어떤 필드가 있느냐 하면 그건 객체 하나 생성해서 까보면 쉽게 알겠지만
필드, 값, 에러내용 등 이 담긴다.
2. Dto 에 데이터를 맵핑할 때 Constraint 를 위반하는 필드가 있을시 발생하는 Exception 을 Handle 하는 메서드 생성
@RestControllerAdvice 및 @ExceptionHandler 라는 애너테이션을 이용한다.
위 애너테이션은 다른 용도로도 많이 사용할 것 같은데 좀더 알아보면 좋을 것 같다.
두 메서드 중 아래의 메서드가 Validation 과정에서 발생하는 Exception 이고
위에 있는 메서드가 다른 서비스 로직 수행중에 발생하는 별도 정의된 Exception 을 처리한다.
3. 위 핸들러에서 반환 되는 값은 아래 코드 참조...
위 코드를 보면 대충 BindingResult 에 어떤 데이터가 들어가는 지 알 수 있다.
위 내용을 확인하고자 포스트 맨에서 Constraint 를 위반하는 데이터를 임의로 집어 넣어 실험했다.
이런식으로 결과가 반환 된다.
!! 더 공부할 내용
1. @RestControllerAdvice 라는 애너테이션을 사용하는 다른 사례
2. 회원가입 Dto에 Gender 라는 Enum 타입 값을 받는 부분이 있는데 여기가 어렵다.
직접 애너테이션을 만들어서 특정 Enum 타입만 허용하도록 만들 수 있는데(가령 여성만 받는다든지)
문제는 Enum에 맵핑되지 않는 String 이 입력되는 경우 Parsing 예외를 먼저 던져서 제대로 에러메세지가 안나감...
다음에는 이부분을 해결해 볼것이다.
관련 레퍼런스 ... https://velog.io/@lsjbh45/Spring-Enum-Type%EC%9C%BC%EB%A1%9C-Request-%EC%9D%B8%EC%9E%90%EB%A5%BC-%EC%A0%84%EB%8B%AC%EB%B0%9B%EC%9D%84-%EB%95%8C-Validation-%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0