HomeGuidesChangelog
GuidesGitHubLog In

Retrofit

A type-safe HTTP client for Android and Java. https://square.github.io/retrofit/

Circuit Breaking

Circuit breaking http client calls is based upon the CircuitBreaker instance provided to a CircuitBreakerCallAdaptor.

// Create a CircuitBreaker
private final CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("testName");

// Create a retrofit instance with CircuitBreaker call adapter
Retrofit retrofit = new Retrofit.Builder()
                .addCallAdapterFactory(CircuitBreakerCallAdapter.of(circuitBreaker))
                .baseUrl("http://localhost:8080/")
                .build();

// Get an instance of your service with circuit breaking built-in.
RetrofitService service = retrofit.create(RetrofitService.class);

Timeouts

To trigger circuit breaking by timeout, the time thresholds should be set on a OkHttpClient instance passed into the Retrofit.Builder.

// Create a CircuitBreaker
private final CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("testName");

final long TIMEOUT = 300; // ms
OkHttpClient client = new OkHttpClient.Builder()
        .connectTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
        .readTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
        .writeTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
        .build();

Retrofit retrofit = new Retrofit.Builder()
        .addCallAdapterFactory(CircuitBreakerCallAdapter.of(circuitBreaker))
        .baseUrl("http://localhost:8080/")
        .client(client)
        .build();

Error responses

Retrofit retrofit = new Retrofit.Builder()
        .addCallAdapterFactory(CircuitBreakerCallAdapter.of(circuitBreaker, (r) -> r.code() < 500));
        .baseUrl("http://localhost:8080/")
        .build();

Rate Limiting

Rate limiting of http client calls is based upon the configuration passed to the RateLimiterCallAdaptor.

RateLimiter rateLimiter = RateLimiter.ofDefaults("testName");

Retrofit retrofit = new Retrofit.Builder()
        .addCallAdapterFactory(RateLimiterCallAdapter.of(rateLimiter))
        .baseUrl("http://localhost:8080/")
        .build();

If the number of calls are exceeded within the period defined by the RateLimiter, a HTTP 429 response (too many requests) will be returned.

Retry

Retry HTTP client calls based upon the Retry instance provided to the RetryCallAdaptor.

// Create a Retry with default configuration
private final Retry retry = Retry.ofDefaults("id");


// Create a Retry with custom configuration
private final Retry retry = Retry.of("id", RetryConfig.<Response<String>>custom()
  .maxAttempts(2)
  .waitDuration(Duration.ofMillis(1000))
  .retryOnResult(response -> response.code() == 500)
  .retryOnException(e -> e instanceof WebServiceException)
  .retryExceptions(IOException.class, TimeoutException.class)
  .ignoreExceptions(BusinessException.class, OtherBusinessException.class)
  .failAfterMaxAttempts(true)
  .build());


// Create a retrofit instance with Retry call adapter
Retrofit retrofit = new Retrofit.Builder()
     .addCallAdapterFactory(RetryCallAdapter.of(retry))
     .baseUrl("http://localhost:8080/")
     .build();


// Get an instance of your service with retry built-in.
RetrofitService service = retrofit.create(RetrofitService.class);

If you don't want to use a fixed wait duration between retry attempts, you can configure an IntervalFunction which is used instead to calculate the wait duration for every attempt. Resilience4j provides several factory methods to simplify the creation of an IntervalFunction.