Spring Framework 6.1 introduces RestClient
a new Fluent API to make synchronous HTTP requests
What You Will build
You will build a Spring Boot web application that consumes and external api with RestClient.
What You Need
- A favorite text editor or IDE
- JDK 1.8 or later
- Gradle 4+ or Maven 3.2+
Setup Project With Spring Initializr
- Navigate to Spring initializr.
- Define the project name example:
spring-web-rest-client
- Choose Project Maven and the language Java.
- Choose Your Java version ex: 17
- Click add dependencies and select:
- Spring Web
- Make sure the Spring Version at least is : 3.2
- Click Generate.
Unzip the Downloaded Zip and open the Project using your favorite text editor or IDE
Overview
In this tutorial, weβre going to demonstrate a range of operations where and How the RestClient
can be used.
Instantiate the RestClient
In order to do that you can simply use the static method create()
private final RestClient restClient = RestClient.create();
Or you can use the builder
for more configuration, eg: set the base url , set default headers...
private final RestClient restClient = RestClient.builder()
.baseUrl("http://localhost:8081/api")
.build();
Retrieve Resource(s)
- Using the
toEntity
to returnResponseEntity
with the body of a given type - Once you get the
ResponseEntity
object you can check the responsestatusCode
and theheaders
// retrieve a list of products
ResponseEntity<List<Product>> response = restClient.get()
.uri("/products")
.retrieve()
.toEntity(new ParameterizedTypeReference<>() {});
// retrieve a product by id
ResponseEntity<Product> response = restClient.get()
.uri("/products")
.retrieve()
.toEntity(Product.class);
Post Resource
To perform a POST
request you just need to use the post()
and specify the contentType
and the body
ResponseEntity<Product> response = restClient.post()
.uri("/products")
.contentType(APPLICATION_JSON)
.body(product)
.retrieve()
.toEntity(Product.class);
Delete Resource
To perform a DELETE
request you just you need to use the delete()
ResponseEntity<Product> response = restClient.delete()
.uri("/products/{productId}", productId)
.retrieve()
.toEntity(Product.class);
Error handling
RestClient
throws RestClientResponseException
when receiving a 4xx or 5xx status code. You can catch the exception and throw a customized exception instead:
ResponseEntity<Product> response = restClient.get()
.uri("/products")
.retrieve()
.onStatus(HttpStatusCode::is4xxClientError, (request, response) -> {
throw new ResponseStatusException(response.getStatusCode(), response.getHeaders())
})
.toEntity(Product.class);
For more flexibility of how you want to handle the response, the exchange
would be the option to go with,
also you need to provide an explicit mapping for your desire Type, eg : ObjectMapper
ObjectMapper mapper = new ObjectMapper();
Product product = restClient.get()
.uri("/products/{productId}", productId)
.exchange((req,res) -> {
if (res.getStatusCode().is2xxSuccessful()) {
return mapper.readValue(res.getBody(), Product.class);
}
if (res.getStatusCode().is4xxClientError()) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "the product does not exist");
}
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "something went wrong");
});
Summary
Congratulations π ! You've covered the main features of the new api RestClient
, You can notice that the new API is more straightforward (fluent) to handle Http Requests compared to the old RestTemplate
Github
The tutorial can be found here on GitHub π
Blog
Check new tutorials on nonestack π