Accessing REST End-point using Spring WebClient
In this blog we will be seeing sample code on how to access the REST End-point using Spring WebClient.
Since there is no active development of RestTemplate
, the recommendation is to use WebClient
.
With reference to my previous blog in this blog will show an approach to perform Integration test or access the Stock App API using Spring WebClient.
In below code,
- I have commented out the Bearer Token, since we are not using it
- First test case uses the RestTemplate for demonstration.
- Second test case, demonstrates the synchronous approach.
- Third one is async way of accessing the end-point.
package com.demo.stock.webclient;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Mono;
@SpringBootTest
public class StockApiWebClient {
// If we have bearer token we can pass as an environment variable.
// currently this is commented
// @Value("${BEARER_TOKEN}")
// private String bearerToken;
public final static String API_ENDPOINT = "https://my-stock-boot-app.herokuapp.com";
public final static String API_ENDPOINT_PATH = "/stock-app/about";
@Test
public void simpleRestTemplateClient() {
HttpHeaders httpHeaders = new HttpHeaders();
//httpHeaders.add("Authorization","Bearer "+this.bearerToken);
String url = UriComponentsBuilder.fromHttpUrl(API_ENDPOINT+API_ENDPOINT_PATH)
//.queryParam("query", "Microsoft News")
.build()
.toUriString();
HttpEntity<?> entity = new HttpEntity<Object>(httpHeaders);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET,entity,String.class);
System.out.println(response.getBody());
assertEquals(HttpStatus.OK, response.getStatusCode());
}
@Test
public void simpleWebClient() {
WebClient client = WebClient.create(API_ENDPOINT);
//Mono represents a container, that is going to publish or emit a single item in the future
// when the item is emitted we can use it.
// in our case it would be a response entity of string
Mono<ResponseEntity<String>> monoResponse = client.get() //fire a GET request
.uri(API_ENDPOINT_PATH)
.retrieve()
.toEntity(String.class);
//To perform a synchronized access, using block method
ResponseEntity<String> response = monoResponse.block();
System.out.println(response.getBody());
assertEquals(200,response.getStatusCodeValue());
}
@Test
public void simpleWebClientAsync() throws InterruptedException {
WebClient client = WebClient.create(API_ENDPOINT);
//Mono represents a container, that is going to publish or emit a single item in the future
// when the item is emitted we can use it.
// in our case it would be a response entity of string
Mono<ResponseEntity<String>> monoResponse = client.get() //fire a GET request
.uri(API_ENDPOINT_PATH) //we can use a template here
// .header("Authorization","Bearer "+this.bearerToken) // commented out
.retrieve()
.toEntity(String.class);
//To perform a Async access, using block method
monoResponse.subscribe(response -> {
System.out.println(response.getBody());
assertEquals(200,response.getStatusCodeValue());
});
System.out.println("Call invoked as async using webclient");
Thread.sleep(5000);//sleep 5 seconds
}
}
In each cases the output will be printed as below,
{"apiName":"Stock Backend API","version":"v1","description":"Simple stock api app, for determining profit or loss based on the investement"}