Simplify Spring Boot 3 HTTP Calls with RestTemplateAdapter & RestClientAdapter
An extensive Spring Boot 3 case collection featuring over 100 practical examples is now available, accompanied by a detailed tutorial that demonstrates how RestTemplateAdapter and RestClientAdapter simplify HTTP request handling, improve code readability, and ensure seamless integration with third‑party APIs, with a commitment to permanent updates.
Spring Boot 3 Case Collection and Adapter Tutorial
The collection now includes more than 100 practical Spring Boot 3 cases and promises permanent free updates for subscribers, who also receive the source code and markdown notes.
1. Introduction
Since Spring 6.1, RestTemplate and RestClient have adapter classes RestTemplateAdapter and RestClientAdapter that implement the HttpExchangeAdapter interface, simplifying HTTP request handling.
The adapters encapsulate HTTP communication details, allowing developers to call third‑party APIs with a uniform, concise API.
Adapter methods
create(RestTemplate restTemplate)– static factory for RestTemplateAdapter (similar for RestClientAdapter). exchange(HttpRequestValues values) – execute request and release response body. exchangeForBodilessEntity(HttpRequestValues values) – execute request and return a response without a body.
exchangeForBody(HttpRequestValues values, ParameterizedTypeReference<T> bodyType)– decode response body to the given type.
exchangeForEntity(HttpRequestValues values, ParameterizedTypeReference<T> bodyType)– return ResponseEntity with body, status and headers. exchangeForHeaders(HttpRequestValues values) – return only response headers. supportsRequestAttributes() – indicate whether the underlying client supports request attributes.
Both adapters share the same request parameter model, regardless of using RestTemplate or RestClient.
2. Practical Cases
2.1 Prepare API
@RestController
@RequestMapping("/api")
public class ApiController {
@GetMapping("/{id}")
public ResponseEntity<User> queryUser(@PathVariable("id") Long id) {
return ResponseEntity.ok(new User(id, "Name - " + id, new Random().nextInt(100)));
}
@GetMapping("/search")
public Map<String, Object> search(User user) {
return Map.of("code", 0, "data", user);
}
@PostMapping("")
public User create(@RequestBody User user) {
return user;
}
public static record User(Long id, String name, Integer age) {}
}2.2 Rest Configuration
@Configuration
public class RestConfig {
@Bean
RestTemplate restTemplate(RestTemplateBuilder builder,
@Value("${pack.api.baseUrl}") String baseUrl) {
return builder.rootUri(baseUrl).build();
}
@Bean
RestClient restClient(@Value("${pack.api.baseUrl}") String baseUrl) {
return RestClient.create(baseUrl);
}
@Bean
RestTemplateAdapter restTemplateAdapter(RestTemplate restTemplate) {
return RestTemplateAdapter.create(restTemplate);
}
@Bean
RestClientAdapter restClientAdapter(RestClient restClient) {
return RestClientAdapter.create(restClient);
}
}2.3 Interface Calls
Inject adapters
private final RestClientAdapter restClientAdapter;
private final RestTemplateAdapter restTemplateAdapter;
public BusinessController(RestClientAdapter restClientAdapter,
RestTemplateAdapter restTemplateAdapter) {
this.restClientAdapter = restClientAdapter;
this.restTemplateAdapter = restTemplateAdapter;
}Call path‑parameter API with RestClientAdapter
@GetMapping("/{id}")
public ResponseEntity<Object> queryUser(@PathVariable("id") Long id) {
HttpRequestValues requestValues = HttpRequestValues.builder()
.setHttpMethod(HttpMethod.GET)
.setUriTemplate("/api/{id}")
.setUriVariable("id", String.valueOf(id))
.build();
return this.restClientAdapter.exchangeForEntity(requestValues,
ParameterizedTypeReference.forType(Map.class));
}Call query‑parameter API with RestTemplateAdapter
@GetMapping("/search")
public Map<String, Object> search(User user) {
HttpRequestValues requestValues = HttpRequestValues.builder()
.setHttpMethod(HttpMethod.GET)
.setUriTemplate("/api/search?id={id}&name={name}&age={age}")
.setUriVariable("id", "888")
.setUriVariable("name", "pack")
.setUriVariable("age", "30")
.build();
return this.restTemplateAdapter.exchangeForBody(requestValues,
ParameterizedTypeReference.forType(Map.class));
}Call POST API with RestClientAdapter
@PostMapping("")
public User create(@RequestBody User user) {
Builder builder = HttpRequestValues.builder()
.setHttpMethod(HttpMethod.POST)
.setUriTemplate("/api");
builder.setBodyValue(user);
HttpRequestValues requestValues = builder.build();
return this.restTemplateAdapter.exchangeForBody(requestValues,
ParameterizedTypeReference.forType(User.class));
}These examples show that regardless of the request type, the parameter model and invocation style remain consistent, greatly enhancing REST access convenience and code maintainability.
End of article.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
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.
