Securely consume RESTful services with Spring’s RestTemplate

Enterprise level software systems nowadays rely on many third party services and resources in order to perform the core functionalities. This has resulted in systems communicating with other services through their public API’s. Most of these API’s being RESTful API’s.

In this post, we will be looking at,

  • Communicating with Rest APIs with the aid of Spring’sRestTemplate.
  • Communicating with a RESTful service secured with Basic Auth / Bearer Token

What is RestTemplate

RestTemplate is Spring’s central class for synchronous client-side HTTP access. The class supports a wide variety of methods for each HTTP method that makes it easy to consume RESTful services. The class is a part of the spring-web which was first introduced in Spring 3.

It's a hassle if we want to make an HTTP Call without using RestTemplate, we need to create a HttpClient and pass the request, required parameters, setup accept headers, perform unmarshalling of response, etc. The Spring RestTemplate abstracts the above operations from you and performs each of them under the hood. It automatically marshals/unmarshals the HTTP request and response bodies. Using RestTemplate is thread safe.

Spring RestTemplate provides the following REST related HTTP methods to perform API requests.

resttemplate 1


Using the Exchange method to communicate with REST API’s:

The REST Template provides a very convenient way to perform HTTP requests of any type through this Exchange method.

public class CustomerDTO {
     private String name;
     private String email;
   
     public CustomerDTO(String name, String email) {
      this.name = name;
      this.email = email;
     }
     public void setName(String name) {
      this.name = name;
     }
     public String getName() {
      return name;
     }
     public void setEmail(String email) {
      this.email = email;
     }
     public String getEmail() {
      return email;
     }
}
   
public class RestTemplateDemo {
         public static void main(String args[]) {
          RestTemplate restTemplate = new RestTemplate();
          String customerAPIUrl = "http://localhost:9080/api/customer";
          HttpEntity <CustomerDTO> request = new HttpEntity <>(new CustomerDTO("ABC", "abc@gmail.com"));
          ResponseEntity <CustomerDTO> customerEntity = restTemplate.exchange(customerAPIUrl, HttpMethod.POST, request, CustomerDTO.class);
          System.out.println("Name:" + customerEntity.getBody().getName());
          System.out.println("Email:" + customerEntity.getBody().getEmail());
         }
}


By executing the exchange method above, a POST request is sent to the server side API to create a new Customer. And depending on how the server side endpoint responds, you will have full access to the response body attributes as well. You could specify which type of ResponseEntity you are expecting the POST to return. You could also specify other HTTP verbs such as GET, PUT, DELETE etc.. with the exchange method.

A simple GET with the RestTemplates exchange method would look like,

        RestTemplate restTemplate = new RestTemplate();
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(customerAPIUrl);
        builder.queryParam("email", "abc@gmail.com");
        ResponseEntity<CustomerDTO> result = restTemplate.exchange(builder.toUriString(), HttpMethod.GET, null, CustomerDTO.class);
        System.out.println("Name:"+result.getBody().getName());
        System.out.println("Email:"+result.getBody().getEmail());

Output:

Name:ABC

Email:abc@gmail.com

The UriComponentsBuilder can be utilized to append query params to the GET request. Similarly to the POST request, we did previously we could define the response type here as well. In order to consume these HTTP requests more securely, we should append the Bearer token or Basic Auth property to the request header.


Setting bearer token for a GET request

          RestTemplate restTemplate = new RestTemplate();
          String customerAPIUrl = "http://localhost:9080/api/customer";
          HttpHeaders headers = new HttpHeaders();
 
          headers.set("Authorization", "Bearer " + accessToken); //accessToken can be the secret key you generate.
          headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
          String requestJson = "{\"email\":\"abc@gmail.com\"}";
          HttpEntity <String> entity = new HttpEntity <> (requestJson, headers);
          ResponseEntity <String> response = restTemplate.exchange(customerAPIUrl, HttpMethod.GET, entity, String.class);

As elaborated in the code above we could use the HttpHeaders of the org.springframework.http package to add the Auth headers which would send in the credentials within the request to the API endpoints.