Backend Development 7 min read

Mastering Spring Boot RestClient: Build Synchronous HTTP Clients Efficiently

This guide explains how to create and configure Spring Boot's RestClient, covering instance creation, request building, header and body handling, response retrieval, error processing, the exchange method, and available client request factories for robust synchronous HTTP communication.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Mastering Spring Boot RestClient: Build Synchronous HTTP Clients Efficiently

Environment: SpringBoot 3.2.1

1. Introduction

RestClient is a synchronous HTTP client that offers a fluent API, abstracting underlying HTTP libraries and enabling easy conversion between Java objects and HTTP requests/responses.

2. Creating a RestClient instance

RestClient is created via the static create() method or a builder that allows selecting the HTTP library, message converters, base URL, default URI variables, headers, interceptors, etc. The resulting client is thread‑safe.

<code>// Simple create
RestClient defaultClient = RestClient.create();

// Builder example
RestClient customClient = RestClient.builder()
    .requestFactory(new HttpComponentsClientHttpRequestFactory())
    .messageConverters(converters -> converters.add(new PackCustomMessageConverter()))
    .baseUrl("http://api.pack.com")
    .defaultUriVariables(Map.of("name", "zs"))
    .defaultHeader("My-Header", "Foo")
    .requestInterceptor(...)
    .requestInitializer(...)
    .build();
</code>

3. Using RestClient

3.1 Request URI

Specify the request URI with uri() . If a default base URL is configured, this step can be omitted. URLs are encoded by default but can be customized via a custom uriBuilderFactory .

<code>RestClient restClient = RestClient.create("http://api.pack.com");
restClient.method(HttpMethod.GET).uri("/users");
</code>

3.2 Request Headers and Body

Add headers with header() or convenience methods such as accept() , contentType() , etc. Set the request body with body(Object) or with a ParameterizedTypeReference for generic types. A callback can write directly to an OutputStream .

<code>RestClient restClient = RestClient.create("http://api.pack.com");
restClient.post()
    .uri("/users")
    .body(new User(666L, "张三", 23))
    .header("X-API-VERSION", "1.0");
</code>

3.3 Retrieving the response

Call retrieve() and then body(Class) or body(ParameterizedTypeReference) to convert the response body. The response can also be obtained as a ResponseEntity to access status and headers.

<code>RestClient restClient = RestClient.create("http://api.pack.com");
User user = restClient.get()
    .uri("/users/666")
    .retrieve()
    .body(User.class);
</code>
<code>ResponseEntity<String> result = RestClient.create("http://api.pack.com")
    .get()
    .uri("/users/666")
    .accept(APPLICATION_JSON)
    .retrieve()
    .toEntity(User.class);
System.out.println("Response status: " + result.getStatusCode());
System.out.println("Response headers: " + result.getHeaders());
System.out.println("Contents: " + result.getBody());
</code>

3.4 Error handling

By default, 4xx/5xx responses throw a RestClientException . Use onStatus to provide custom handling.

<code>String result = restClient.get()
    .uri("/users/{id}", id)
    .retrieve()
    .onStatus(HttpStatusCode::is4xxClientError,
        (request, response) -> {
            throw new MyCustomRuntimeException(response.getStatusCode(),
                response.getHeaders());
        })
    .body(String.class);
</code>

3.5 Exchange

The exchange method gives full access to the underlying request and response, bypassing the default status handling.

<code>RestClient restClient = RestClient.create("http://api.pack.com");
restClient.post()
    .uri("/users/666")
    .body(new User())
    .header("X-API-VERSION", "1.0")
    .exchange((request, response) -> {
        if (response.getStatusCode().is4xxClientError()) {
            throw new RuntimeException(String.format("status: %d, headers: %s",
                response.getStatusCode(), response.getHeaders()));
        } else {
            return response.getBody();
        }
    });
</code>

3.6 Client request factories

RestClient delegates HTTP execution to a ClientRequestFactory . Available implementations include JdkClientHttpRequestFactory , HttpComponentsClientHttpRequestFactory , JettyClientHttpRequestFactory , ReactorNettyClientRequestFactory , and SimpleClientHttpRequestFactory . If none is specified, RestClient picks an implementation based on the classpath (Apache/Jetty) or Java’s HttpClient when the java.net.http module is present.

End of article.

backendJavaHTTPAPISpringBootRestClient
Spring Full-Stack Practical Cases
Written by

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.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.