Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make retryable calls using RestClient

I would like to enforce the Spring 6.1 RestClient to perform all http calls with a retry mechanism. Ideally I would like to replicate this behavior achievable using RestTemplate and spring-retry RetryTemplate:

RetryTemplate retryTemplate = retryTemplate(retryProperties);

return new RestTemplate(requestFactory) {
  @Override
  public <T> ResponseEntity<T> exchange(
      URI url,
      HttpMethod method,
      HttpEntity<?> requestEntity,
      Class<T> responseType) {
    return retryTemplate.execute(
        context -> super.exchange(url, method, requestEntity, responseType));
  }
};

For numerous reasons this approach is not valid in this case, but I'm looking for a solution to achieve something similar using RestClient

What would be alternative solutions to this problem?

like image 808
etalol Avatar asked Apr 27 '26 22:04

etalol


1 Answers

You can usually set a RetryHandler/Strategy in the HttpClient. Depending on which client you use, the implementation may look different.

If you are using Apache Http Client 5, you can set a RetryStrategy in this way:

    @Bean
    fun clientHttpRequestFactory(): ClientHttpRequestFactory {
        val maxRetryAttempts = 3
        val delayInMillis = 300L
        val client = HttpClients.custom()
            // Will only retry on low level I/O exceptions or status codes 429, 503
            .setRetryStrategy(DefaultHttpRequestRetryStrategy(maxRetryAttempts, TimeValue.ofMilliseconds(delayInMillis)))
            .build()
        return HttpComponentsClientHttpRequestFactory(client)
    }
    
    @Bean
    fun customRestClient(clientHttpRequestFactory: ClientHttpRequestFactory): RestClient {
        return RestClient.builder()
            .requestFactory(clientHttpRequestFactory)
            .build()
    }

Be aware that the DefaultHttpRequestRetryStrategy will only retry low lewel IO exceptions or status code 429, 503. If you need something specific, you could implement your own RetryStrategy.

Alternatively, you can also reuse your current RestTemplate and pass it to the RestClient Builder:

    @Bean
    fun customRestClient(customRetryRestTemplate: RestTemplate): RestClient {
        return RestClient
            .builder(customRetryRestTemplate)
            .build()
    }

like image 108
WhiteCherry Avatar answered Apr 30 '26 11:04

WhiteCherry