[SpringBoot] GlobalException 활용한 파라미터 유효성 검증 리팩토링

파라미터 유효성 검증에 대한 코드 리팩토링 과정을 설명한다.

 

파라미터 유효성 규칙 추가

처음에 유효성 검증을 위해 회원가입 컨트롤러에서 CreateMemberRequest DTO를 받아서 회원가입 로직을 처리하고. 앞에 @Validated를 붙이고 DTO 필드에 어노테이션을 이용하여 필드마다 유효성 규칙을 추가하였다. 파라미터에 대한 유효성 검증을 하였다.

 

위 방식의 문제는 유효성 규칙을 통과 못했을때 응답하는 messgae가 너무 정형화 되지않은 형식으로 된다. 사용자한테 아래 메시지대로 보여주면 이해하지 못하므로 필요한 메시지를 정형화 시켜야 된다.

 

 

BindingResult 이용해서 파라미터 유효성 에러 메시지 정형화

메시지를 정형화 되도록 하기 위해서 첫째로 BindingResult를 쓰는 방법이 있다. 스프링이 제공하는 유효성 검증 에러를 보관하는 객체인데 이것은 무조건 검증하려는 객체 뒤에 위치시켜야 한다.

 

bindingResult 객체의 hasError() 함수로 보관한 에러가 있다면 errorMap에 필드명과 메시지를 담아서 Json으로 변환시킨후 ValidationException 에러를 발생시켜 json을 응답하였다. 그 결과 아래처럼 메시지가 정형화 돼서 전달이 됐다 이러면 사용자에게 에러 원인을 잘 전달 할 수 있다.

 

하지만 한가지 꺼림직한게 있다. 회원가입 컨트롤러에 에러 처리 로직이 들어가는게 마음에 들지 않았다. 왜냐하면 이것은 SRP 원칙에 어긋나기 때문이다. 회원가입 컨트롤러에는 서비스 로직을 실행시키고 서비스에서 반환받은 값으로 응답 메시지를 만들어 반환시켜주는 역할만 해야 한다. 그래서 GlobalException을 활용하였다.

 

GlobalException 이용해서 파라미터 유효성 에러 메시지 정형화

특별한 에러 처리 없이 GlobalException을 적용하려면 Unchecked Exception에 해당해야 한다. Checked Exception은 try catch문으로 에러 처리 로직을 넣어야 하기 때문에 GlobalException을 사용하는 의미가 없다.

유효성에러는 특별한 에러처리가 없이 발생하므로 Unchecked Exception이고 그래서 무슨 런타임 에러가 발생하는지 알아야 한다.

 

 유효성을 실패해보니 MethodArgumentNotValidException 에러가 발생하는것을 알았고 

 

그리고 GlobalException에 등록한다. 컨트롤러에서 처리했던 errorMap 만드는 로직을 GlobalException에서 하니 컨트롤러는 원래대로 자신이 해야할 일만 하게 되었고 SRP원칙이 지켜져 가독성과 유지보수가 향상되었다.

 

한가지 주의점은 BindingResult를 지워야 한다는 것이다. 유효성 검증을 해서 에러를 보관하는 역할을 하기 때문에 Runtime Exception이 발생안해서 GlobalException 쪽으로 전달이 되지 않는다. 

 

댓글

Designed by JB FACTORY