We can basically consume any REST service synchronously as well as asynchronously. In the Spring Boot framework, we have RestTemplate that performs an HTTP request synchronously and WebClient which performs request asynchronously.
So, in this blog, we will discuss how we can invoke any REST service with WebClient with example.
What is WebClient?
This asynchronous HTTP client(WebClient) is introduced in Spring 5 and it is a part of Spring WebFlux(reactive web framework). It is nonblocking and reactive client to perform an HTTP request which is replacing RestTemplate
Add Dependencies
Add the following dependencies in your existing Spring boot application
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<dependency> | |
<groupId>org.springframework.boot</groupId> | |
<artifactId>spring-boot-starter-webflux</artifactId> | |
</dependency> |
And if you are creating your project from scratch, then go to https://start.spring.io/ and don’t forget to add Reactive Web as a dependency.
Calling Rest Service with WebClient
Let’s see how we can consume any external service with some code snippet.
In the following example, we are going to make the GET request to https://jsonplaceholder.typicode.com/posts/1 and it will return the JSON in the following format.
{ "userId": 1, "id": 1, "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto" }
Create an instance of WebClient
We can create the instance of WebClient using the static factory method that is create().
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//create() Method accepts the String value as parameter. Here, we are initializing with the baseUrl. | |
WebClient webClient = WebClient.create("https://jsonplaceholder.typicode.com") |
Another way of creating a client is by a builder. It allows more customization like default header, defaultUriVariables, etc.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
WebClient client = WebClient.builder() | |
.baseUrl("https://jsonplaceholder.typicode.com") | |
.build(); |
Make HTTP request and handle the response
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public Mono<UserDetails> callToExternalService() { | |
return client | |
.get() | |
.uri("posts/1") | |
.retrieve() | |
.bodyToMono(UserDetails.class); | |
} |
In the above example, first of all, we need to specify that we want to make a GET request using get() method followed by adding the URI. And the retrieve() method simply retrieve the response body and then it is extracted to a Mono and that’s why the return type is Mono of POJO.
The retrieve() method can also be replaced with exchange() method in the following way.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public Mono<UserDetails> callToExternalService() { | |
return WebClient | |
.builder() | |
.baseUrl("https://jsonplaceholder.typicode.com") | |
.build() | |
.get() | |
.uri("posts/1") | |
.exchange() | |
.flatMap(clientResponse -> clientResponse.bodyToMono(UserDetails.class)); | |
} |
With the exchange() method you have more control over the response body than retrieve() method as it simply gets the response body.
Conclusion
It’s pretty straightforward to interact with any external service with WebClient. Create an instance of WebClient, make HTTP request and handle the response the way you want. Hope this is helpful, please feel free to provide your suggestions:).
References
https://www.baeldung.com/spring-5-webclient
https://docs.spring.io/spring/docs/5.1.6.RELEASE/spring-framework-reference/web-reactive.html#webflux-client