Best pratice: How to make a customize RestTemplate auto retry it's failed api call?

Viewed 241

I have written an customize ResponseErrorHandler of RestTemplate as following code:

class ExternalApiErrorHandler(
    @Autowired
    val xxxAuthService: XXXAuthService
) : ResponseErrorHandler {
    companion object {
        private val logger: LogService = LogServiceImpl(ExternalApiErrorHandler::class.java)
    }

    override fun hasError(response: ClientHttpResponse): Boolean {
        return (response.statusCode.is4xxClientError || response.statusCode.is5xxServerError)
    }

    override fun handleError(url: URI, method: HttpMethod, response: ClientHttpResponse) {
        if (response.statusCode == HttpStatus.UNAUTHORIZED && ExternalApiEnpoint.isExternalApiEndpoint(url = url.toString())) {
            xxxAuthService.callLogin();
    }
}

}

Right now, I only call auto login if the URL belong to the specific list ExternalApiEndpoint and the status code is 403. But I also want it to automatic retry it's failed action (like restTemplate.exchange, restTemplate.postForEntity,....). So my questions is: What is the best way to do this? Should I handle it also in the handleError() method or handle it separately with each API call? Any keyword for this problem would also be very helpful!!! Thanks in advance.

Here is a code example of my service api:

@Service
class OrderApi(
    @Autowired
    private val externalApiEnpoint: ExternalApiEnpoint,
    @Autowired
    private val restTemplate: RestTemplate
) {

    private var logService: LogService = LogServiceImpl(OrderApi::class.java)

    fun create(contentRequest: OrderSendXXXDto, accessToken: String): ResponseEntity<OrderXXXResponseDto> {
        val requestUri = UrlBuilder(ExternalApiEnpoint.orderCreateUrl)
            .toString()

        val headers = HttpHeaders()
        headers.contentType = MediaType.APPLICATION_FORM_URLENCODED
        val body = HttpUtils.convertObject2Map(contentRequest)
        val request = HttpEntity(body, headers)
        val response = restTemplate.postForEntity(requestUri, request, OrderXXXResponseDto::class.java)

        return response
    }
}
0 Answers
Related