Back-End (web)

[kotlin][coroutine] awaitRetrieve

햄과함께 2020. 4. 5. 00:57
320x100

응답이 200이고 응답 body에 대한 처리만 하고 싶은 경우 retrieve.
이 외에 응답 코드가 4xx, 5xx 등 특정 코드에 따라 다른 결과를 주고 싶거나 응답 헤더를 사용하고 싶은 경우는 exchange를 사용하자.

(참고 : [spring] webClient error 처리)


평소에 4xx, 5xx 일 때 에러는 신경안쓰고 body에 대해서만 고려해서 retrieve를 많이 사용했었다.

coroutine으로 전환하면서  awaitRetrieve 를 쓰려고 했는데 없었다.

 

그러나 package org.springframework.web.reactive.function.client.WebClientExtension 에  awaitExchange  함수는 있다. (참고)

suspend fun RequestHeadersSpec<out RequestHeadersSpec<*>>.awaitExchange(): ClientResponse =
		exchange().awaitSingle()

spring-webflux:5.2.1 기준.

 

그래서 awaitExchange로 awaitRetrieve Extension을 만들어서 이를 사용했다.

suspend inline fun <reified T : Any> WebClient.RequestHeadersSpec<out WebClient.RequestHeadersSpec<*>>.awaitRetrieve(): T {
  return this.awaitExchange().also {
    if (it.statusCode().isError) {
      throw it.createException().awaitFirst()
    }
  }.awaitBody()
}

 

status를 보고 error(4xx, 5xx)인 경우 적절한 WebClientResponseException를 만들어서 예외를 던진다.

예를 들어 internal error인 경우  WebClientResponseException.InternalServerError 예외를 던진다.

webClient에서 만들어주는 에러말고 커스텀 에러를 던지고 싶다면 4번째 줄에  throw it.createException().awaitFirst() 을 수정하면된다.

 

val response = WebClient.create().get()
                  .(생략)
                  .awaitRetrieve<CustomResponseBody>()

사용은 위와 같이.

CustomResponseBody가 우리가 기대하는 응답 body이다.

320x100