Handling Null in Request DTO
About
Spring의 컨트롤러에서 @RequestBody
어노테이션을 이용하면 HTTP body에 있는 JSON 데이터를 객체로 변환해 받아올 수 있다. JSON에 있는 모든 데이터가 꼭 필요하지 않아서 오지 않으면 무시하는 경우도 있지만, 전부 필요할 수도 있다.
Java
Java에서는 null checking을 언어 차원에서 지원하고 있지는 않다. 하지만 Validation의 어노테이션을 통해 검증할 수 있다.
@NotNull
어노테이션으로 age
가 null
이면 오류를 반환한다.
Kotlin
코틀린에서는 nullable 타입과 non-nullable 타입을 구분하여 null safe하게 개발할 수 있다. 그런데 약간의 주의가 필요하다.
일단 위의 코드를 코틀린으로 바로 바꾸면 이렇게 될 것이다.
하지만 여기서 여러 가지를 수정해야 한다.
코틀린은 nullable과 non-nullable 타입을 타입 뒤에
?
를 붙이는 것으로 구분한다. 따라서age
는 애초에null
이 될 수 없다.이렇게 작성했을 때 age가 null로 들어오게 된다면,
@field:NotNull
어노테이션을 통해 validation 로직이 실행되기 전에 변수에 값을 할당하는 과정부터 예외가 발생한다. 따라서 여기서 이 어노테이션은 의미가 없다.원래
@NotNull
이 붙어있지 않았던imageUrl
은 nullable 타입이 되어야겠다.
수정사항을 반영할 때 이렇게 해결하는 방법이 있다.
다만 해당 DTO를 컨트롤러에서 받아서 사용하게 될텐데, age
는 실제로 null이 아님에도 불구하고 age
뒤에 ?
를 붙이는 등 null checking을 진행해야 한다. 불편하기도 하고, 깔끔하지도 않다.
Solution
내 생각엔 이 방법이 가장 깔끔할 것 같다. 다음과 같이 진행하자.
null로 받아도 되는 필드는 단순히
?
를 붙인다. 아니면 붙이지 말.ProfileUpdateRequest.ktHttpMessageNotReadableException
을 exception handler에서 잡고, 필요하다면 추가 작업을 통해MissingKotlinParameterException
을 내부적으로 타입을 체크해 메시지를 반환한다.
참고로, non-nullable 타입에 null이 담기려고 하면 HttpMessageNotReadableException
이 발생하지만, 예외가 발생한 진짜 원인인 MissingKotlinParameterException
과는 직접적인 클래스 관계가 없다.
REF
Yoon Sung's Blog - Kotlin + Spring 에서 Dto에 null 요청을 받았을때 처리하기
해당 이슈와 관련하여 자세하게 적혀있다. 모든 내용은 이 글을 참고한다.
Last updated