1. Web 요청 모델과 Service 요청 모델을 분리했는가?
- spring-boot-starter-validation이 표현 계층 하위에서 필요한지 생각해 보기(domain이나 application...등등에서 불필요함!)
data class ReserveProductWebRequest(
....
) {
fun mapToServiceRequest(): ReserveProductRequest {
return ReserveProductRequest(
shopId,
products.map { it.mapToServiceObject() },
LocalDateTime.parse(reservedAt)
)
}
}
2. 중첩해서 검증하고 싶다면?
- 중첩 DTO의 예시는 다음과 같음
- ReserveProductWebRequest(검증 대상)
- shopId: Long
- products: List<ReservedWebProduct> (중첩 검증 대상, 이곳에 @Valid 붙일 것)
- productId: Long
- ...중략
- reservedAt: String
- ReserveProductWebRequest(검증 대상)
3. Handler에 @RestControllerAdvice가 걸려 있는가?
- JSON으로 예외 응답을 내려주고 싶은 경우에는 @ControllerAdvice가 아닌, @RestControllerAdvice 사용
- 대신 응답을 커스텀으로 내려주는 경우에(ResponseEntity 미사용) @ResponseStatus를 사용할 것
4. data class를 요청 dto로 사용하는 경우
data class ReserveProductWebRequest(
@field:NotNull(message = "예약 대상 가게 식별자는 필수입니다.")
val shopId: Long?,
@field:Valid
@field:NotNull(message = "예약 상품 목록은 필수입니다.")
val products: List<ReservedWebProduct>?,
@field:DateValid
@field:NotNull(message = "예약 시간은 필수입니다.")
val reservedAt: String?
) {
fun mapToServiceRequest(): ReserveProductRequest {
return ReserveProductRequest(
shopId!!,
products!!.map { it.mapToServiceObject() },
LocalDateTime.parse(reservedAt!!)
)
}
}
- validation 기능 이용하고 싶다면, 위와 같이 null 가능 타입으로 선언하고, 사용할 때는 단언
- null이 가능하지 않은 타입 사용할 경우, HttpMeesageNotReadableException 발생 가능함
- 위의 경우에는 무엇 때문에 예외가 발생하는지 클라이언트에서 알기 어려움
- @field:NotNull 처럼 @field는 data class를 사용하는 경우에만 사용함
- 기본 class에서는 @NotNull만 사용해도 동작함. 단, 코틀린 1.6.10 버전부터는 해당 이슈가 해결된 것으로 보임!
'개발(레거시) > 문제 해결' 카테고리의 다른 글
레거시 코드를 헥사고날 아키텍처로 전환(Final) - 회원 도메인에서 웹, 인증 어댑터 분리 (0) | 2023.04.04 |
---|---|
레거시 코드를 헥사고날 아키텍처로 전환(2) - 회원 도메인에서 읽기 전용 유스 케이스 분리, 영속성 어댑터 만들기 (0) | 2023.03.31 |
레거시 코드를 헥사고날 아키텍처로 전환(1) - 회원 도메인에서 쓰기 전용 유스 케이스 분리 (2) | 2023.03.29 |
아르티 리팩터링 기록 - publish (0) | 2023.01.23 |
아르티 아키텍처 디자인에 대해서 끄적 (0) | 2023.01.23 |