Reputation: 71
I've implemented a java method which call to external services via a Resttemplate. As well, i've implemented some additional business logic also inside that method. How can i implement a retry mechanism for these rest calls. Need to consider below points as well.
Upvotes: 7
Views: 27554
Reputation: 1209
for rest api call you can implement the retry mechanism on the client level where actual rest call going
@Retryable(value = Exception.class, maxAttemptsExpression = "${retry.maxAttempts}", backoff = @Backoff(delayExpression = "${retry.maxDelay}"))
public Optional<T> getApiCall(String url, String token, Class<T> resClass) {
ResponseEntity<T> response = null;
try {
logger.info(url);
// create headers
HttpHeaders headers = new HttpHeaders();
// set `accept` header
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.setBearerAuth(token);
// set custom header
// headers.set("x-request-src", "desktop");
// build the request
HttpEntity<String> entity = new HttpEntity<>("", headers);
// use exchange method for HTTP call
try {
response = this.restTemplate.exchange(url, HttpMethod.GET, entity, resClass, 1);
} catch (HttpStatusCodeException e) {
return errorService.throwException(HttpStatus.NOT_FOUND, EKDError.LIFPRO406);
}
if (response.getStatusCode() == HttpStatus.OK) {
return Optional.ofNullable(response.getBody());
} else {
return errorService.throwException(HttpStatus.NOT_FOUND, EKDError.LIFPRO406);
}
} catch (HttpClientErrorException | HttpServerErrorException e) {
logger.error("Exception in api call : ", e);
return errorService.throwException(HttpStatus.INTERNAL_SERVER_ERROR, EKDError.LIFPRO407);
}
}
now max attempts and delay is configurable set application.properties maxAttemptsExpression = "${retry.maxAttempts}", backoff = @Backoff(delayExpression = "${retry.maxDelay}"
Upvotes: 0
Reputation: 8011
Spring provides a retry mechanism with @Retry annotations. You have to use the following dependency.
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.1.5.RELEASE</version>
</dependency>
Spring provides the following annotations.
Spring retry annotations
@EnableRetry – to enable spring retry in spring boot project
@Retryable – to indicate any method to be a candidate of retry
@Recover – to specify fallback method
I provide below the sample code.
@Configuration
@EnableRetry
@SpringBootApplication
public class MyApplication {
}
You can refer the complete example to know more about it.
Upvotes: 12
Reputation: 111
You may add retry mechanism inside HttpClient
and use it for RestTemplate
, somethng like this:
@Bean
public ClientHttpRequestFactory clientFactory() {
HttpClient httpClient = HttpClients.custom()
.setRetryHandler((exception, executionCount, context) -> {
if (executionCount > 3) {
log.warn("Maximum retries {} reached", 3);
return false;
}
if (<some condition for retry>) {
log.warn("Retry {}", executionCount);
return true;
}
return false;
})
.build();
return new HttpComponentsClientHttpRequestFactory(httpClient);
}
@Bean
public RestTemplate customRestTemplate(@Qualifier("clientFactory") ClientHttpRequestFactory clientFactory){
return new RestTemplate(clientFactory);
}
Upvotes: 11