Spring Framework 6.1 M2 introduces the `RestClient`, a new synchronous HTTP client. As the name suggests, `RestClient` offers the fluent API of `WebClient` with the infrastructure of `RestTemplate`.
Fourteen years ago, when `RestTemplate` was introduced in Spring Framework 3.0, we quickly discovered that exposing every capability of HTTP in a template-like class resulted in too many overloaded methods. In Spring Framework 5, we therefore used a fluent API for the reactive `WebClient`. With `RestClient` we are introducing a HTTP client that offers an API similar to `WebClient`, and that uses the message converters, request factories, interceptors, and other underlying components of `RestTemplate`.
## Creating a `RestClient`
You can create a `RestClient` using one of the static `create` methods. You can also use `RestClient::builder` to get a builder with further options, such as specifying the HTTP client to use, setting a default URL, path variables, and headers, or registering interceptors and initializers.
Using `RestClient::create(RestTemplate)`, you can initialize a `RestClient` with the configuration of an existing `RestTemplate`.
## Retrieve
Let’s create a `RestClient`, use it to set up a basic `GET` request, and retrieve the contents of a site as string using `retrieve`:
RestClient restClient = RestClient.create();
String result = restClient.get()
.uri(“https://example.com”)
.retrieve()
.body(String.class);
System.out.println(result);
If you’re interested in the response status code and headers, and not just the contents, you can use `toEntity` to get a `ResponseEntity`:
ResponseEntity result = restClient.get()
.uri(“https://example.com”)
.retrieve()
.toEntity(String.class);
System.out.println(“Response status: ” + result.getStatusCode());
System.out.println(“Response headers: ” + result.getHeaders());
System.out.println(“Contents: ” + result.getBody());
`RestClient` can also convert JSON to objects, using Jackson under the hood. In fact, it can convert all types that `RestTemplate` supports, as it uses the same [message converters](). Note the usage of uri variables, and that the `Accept` header is set to JSON.
int id = …
Pet pet = restClient.get()
.uri(“https://petclinic.example.com/pets/{id}”, id)
.accept(APPLICATION_JSON)
.retrieve()
.body(Pet.class);
### POST
Doing a `POST` request is just as simple, like so:
Pet pet = …
ResponseEntity response = restClient.post()
.uri(“https://petclinic.example.com/pets/new”)
.contentType(APPLICATION_JSON)
.body(pet)
.retrieve()
.toBodilessEntity();
### Error handling
By default, `RestClient` throws a subclass of `RestClientException` when receiving a 4xx or 5xx status code. This behavior can be overriden using status handlers, like so:
String result = restClient.get()
.uri(“https://example.com/this-url-does-not-exist”)
.retrieve()
.onStatus(HttpStatusCode::is4xxClientError, (request, response) -> {
throw new MyCustomRuntimeException(response.getStatusCode(), response.getHeaders())
})
.body(String.class);
## Exchange
The `RestClient` offers the `exchange` method for more advanced scenarios, as it provides access to the underlying HTTP request and response. The previously mentioned status handlers are _not_ applied when you use `exchange`, because the exchange function already provides access to the full response, allowing you to perform any error handling necessary:
Pet result = restClient.get()
.uri(“https://petclinic.example.com/pets/{id}”, id)
.accept(APPLICATION_JSON)
.exchange((request, response) -> {
if (response.getStatusCode().is4xxClientError()) {
throw new MyCustomRuntimeException(response.getStatusCode(), response.getHeaders());
}
else {
Pet pet = convertResponse(response);
return pet;
}
});
## Support for `RestClient`
The `RestClient` is just one of the [many features]() that Spring Framework 6.1 offers. Various components already support `RestClient`: you can test its usage through the [`MockRestServiceServer`](), or use it as the backend for [`@HttpExchange` interfaces]().
Additionally, [Spring Boot 3.2 M1]() will include support for the `RestClient`.Read More
References
Back to Main