Site icon API Security Blog

New in Spring 6.1: RestClient

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

Exit mobile version