retrofit-spring-boot-starter: A Lightweight HTTP Client Framework for Spring Boot
The retrofit-spring-boot-starter library provides a Spring Boot‑compatible, type‑safe HTTP client built on Retrofit, offering easy integration, customizable OkHttpClient injection, annotation‑based interceptors, connection‑pool management, logging, retry, error decoding, circuit‑breaker support, and flexible call adapters and converters for modern Java backend development.
In Spring Boot projects, using okhttp, httpClient or RestTemplate for HTTP calls can be cumbersome and hard to manage centrally. The retrofit-spring-boot-starter offers a lightweight, type‑safe HTTP client based on Retrofit that integrates seamlessly with Spring Boot, simplifying request handling and providing many enhancements. The current version is 2.2.2.
Retrofit is a type‑safe HTTP client for Android and Java that supports interface‑based request definitions. Since Retrofit does not natively support Spring Boot, this starter bridges the gap, enabling rapid integration and adding features such as custom OkHttpClient injection, annotation‑driven interceptors, connection‑pool management, logging, retry, error decoding, global interceptors, circuit‑breaker (Sentinel) support, and micro‑service HTTP calls.
Key Features
Custom OkHttpClient injection
Annotation‑based interceptors
Connection‑pool management
Logging
Request retry
Error decoder
Global interceptor
Circuit‑breaker degradation
HTTP calls between micro‑services
Call adapters and data converters
Quick Start
Dependency
<dependency>
<groupId>com.github.lianjiatech</groupId>
<artifactId>retrofit-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>Define HTTP Interface
The interface must be annotated with @RetrofitClient. HTTP method annotations follow the official Retrofit documentation.
@RetrofitClient(baseUrl = "${test.baseUrl}")
public interface HttpApi {
@GET("person")
Result<Person> getPerson(@Query("id") Long id);
}Inject and Use
@Service
public class TestService {
@Autowired
private HttpApi httpApi;
public void test() {
// call httpApi methods here
}
}HTTP Annotation Reference
All HTTP request annotations are the native Retrofit annotations; refer to the Retrofit documentation for details.
Configuration
Various properties can be set in application.yml to control logging, connection pools, retry, error decoding, and circuit‑breaker behavior.
retrofit:
enable-response-call-adapter: true
enable-log: true
pool:
test1:
max-idle-connections: 3
keep-alive-second: 100
test2:
max-idle-connections: 5
keep-alive-second: 50
disable-void-return-type: false
logging-interceptor: com.github.lianjiatech.retrofit.spring.boot.interceptor.DefaultLoggingInterceptor
retry-interceptor: com.github.lianjiatech.retrofit.spring.boot.retry.DefaultRetryInterceptor
global-converter-factories:
- retrofit2.converter.jackson.JacksonConverterFactory
global-call-adapter-factories:
- com.github.lianjiatech.retrofit.spring.boot.core.BodyCallAdapterFactory
- com.github.lianjiatech.retrofit.spring.boot.core.ResponseCallAdapterFactory
enable-degrade: true
degrade-type: sentinel
resource-name-parser: com.github.lianjiatech.retrofit.spring.boot.degrade.DefaultResourceNameParserAdvanced Features
Custom OkHttpClient Injection
Define a static method returning OkHttpClient.Builder and annotate it with @OkHttpClientBuilder inside the Retrofit interface.
@RetrofitClient(baseUrl = "http://ke.com")
public interface HttpApi3 {
@OkHttpClientBuilder
static OkHttpClient.Builder okhttpClientBuilder() {
return new OkHttpClient.Builder()
.connectTimeout(1, TimeUnit.SECONDS)
.readTimeout(1, TimeUnit.SECONDS)
.writeTimeout(1, TimeUnit.SECONDS);
}
@GET("person")
Result<Person> getPerson(@Url String url, @Query("id") Long id);
}Annotation‑Based Interceptor
Implement BasePathMatchInterceptor and annotate the interface with @Intercept to apply URL‑based interception.
@Component
public class TimeStampInterceptor extends BasePathMatchInterceptor {
@Override
public Response doIntercept(Chain chain) throws IOException {
Request request = chain.request();
HttpUrl url = request.url();
long timestamp = System.currentTimeMillis();
HttpUrl newUrl = url.newBuilder()
.addQueryParameter("timestamp", String.valueOf(timestamp))
.build();
Request newRequest = request.newBuilder().url(newUrl).build();
return chain.proceed(newRequest);
}
} @RetrofitClient(baseUrl = "${test.baseUrl}")
@Intercept(handler = TimeStampInterceptor.class, include = {"/api/**"}, exclude = "/api/test/savePerson")
public interface HttpApi {
@GET("person")
Result<Person> getPerson(@Query("id") Long id);
@POST("savePerson")
Result<Person> savePerson(@Body Person person);
}Custom Intercept Annotation (@Sign)
Define a custom annotation marked with @InterceptMark that includes include(), exclude(), and handler(). Implement the handler to add signature headers.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@InterceptMark
public @interface Sign {
String accessKeyId();
String accessKeySecret();
String[] include() default {"/**"};
String[] exclude() default {};
Class<? extends BasePathMatchInterceptor> handler() default SignInterceptor.class;
} @Component
public class SignInterceptor extends BasePathMatchInterceptor {
private String accessKeyId;
private String accessKeySecret;
public void setAccessKeyId(String accessKeyId) { this.accessKeyId = accessKeyId; }
public void setAccessKeySecret(String accessKeySecret) { this.accessKeySecret = accessKeySecret; }
@Override
public Response doIntercept(Chain chain) throws IOException {
Request request = chain.request();
Request newReq = request.newBuilder()
.addHeader("accessKeyId", accessKeyId)
.addHeader("accessKeySecret", accessKeySecret)
.build();
return chain.proceed(newReq);
}
} @RetrofitClient(baseUrl = "${test.baseUrl}")
@Sign(accessKeyId = "${test.accessKeyId}", accessKeySecret = "${test.accessKeySecret}", exclude = {"/api/test/person"})
public interface HttpApi {
@GET("person")
Result<Person> getPerson(@Query("id") Long id);
@POST("savePerson")
Result<Person> savePerson(@Body Person person);
}Connection Pool Management
Define multiple pools in configuration and select a pool per interface via poolName attribute.
retrofit:
pool:
test1:
max-idle-connections: 3
keep-alive-second: 100
test2:
max-idle-connections: 5
keep-alive-second: 50 @RetrofitClient(baseUrl = "${test.baseUrl}", poolName = "test1")
public interface HttpApi {
@GET("person")
Result<Person> getPerson(@Query("id") Long id);
}Logging
Enable global or per‑interface logging via retrofit.enableLog and configure level (ERROR, WARN, INFO, DEBUG, TRACE) and strategy (NONE, BASIC, HEADERS, BODY).
Retry
Apply @Retry to enable automatic retry with configurable max retries, interval, and rules (status not 2xx, IO exception, any exception).
Error Decoder
Implement ErrorDecoder to translate HTTP errors or exceptions into custom runtime exceptions.
Global Interceptor
Implement BaseGlobalInterceptor and register as a Spring bean to apply headers or other logic to all outgoing requests.
@Component
public class SourceInterceptor extends BaseGlobalInterceptor {
@Override
public Response doIntercept(Chain chain) throws IOException {
Request request = chain.request();
Request newReq = request.newBuilder()
.addHeader("source", "test")
.build();
return chain.proceed(newReq);
}
}Circuit‑Breaker (Sentinel)
Enable degradation with enable-degrade: true, set degrade-type: sentinel, and optionally configure @Degrade on interfaces or methods, or provide fallback / fallbackFactory implementations.
Micro‑service Calls
Implement ServiceInstanceChooser (e.g., SpringCloudServiceInstanceChooser) and use
@RetrofitClient(serviceId = "${service.id}", path = "/m/count")to call other services.
Call Adapters and Converters
The starter registers BodyCallAdapterFactory and ResponseCallAdapterFactory globally, allowing return types such as Call<T>, CompletableFuture<T>, Void, Response<T>, or any POJO. Global converter factories can be set (default Jackson) and overridden per interface.
Overall, retrofit-spring-boot-starter provides a comprehensive, configurable, and Spring‑friendly HTTP client solution for modern Java backend development.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
