Blog

A common Pitfall of Spring Boot's RestTemplate

03.08.2021 by Manuel Gerding - 3 min read

One of the most fundamental advantages of Spring Boot is the paradigm of convention over configuration reducing the overhead heavily. Even so, there is a tiny pitfall in the default behavior of Spring Boot's RestTemplateBuilder that is probably not what you are really aiming for. So, be sure that you have configured it manually.

Set the Stage: Use Defaults

So what is the problem with the RestTemplateBuilder? To expose this, we need to have two simple applications that communicate with each other over HTTP. In this blog post, we use a simple demo online shop that consists of a Gateway microservice requesting an endpoint of another microservice (called Hotdeals) over HTTP. The following listing shows the relevant parts of the code, you can check the full source code of the demo online shop in the GitHub repository.

@RestController
@RequestMapping("/products")
public class ProductsController {
   private final RestTemplate restTemplate;
   @Value("${rest.endpoint.hotdeals}")
   private String urlHotDeals;
   ...
   public ProductsController(RestTemplate restTemplate) {
       this.restTemplate = restTemplate;

   @GetMapping
   private List<Product> getHotDealsProduct() {
       return this.restTemplate.exchange(
         this.urlHotDeals,
         HttpMethod.GET,
         null,
         this.productListTypeReference
       ).getBody();
   }
}

While this code works fine under good conditions, the problem comes to light under turbulent conditions - for example, network problems such as network package loss. So how can we verify what will happen? Without changing the code or doing too much low-level network stuff!

This is a problem steadybit can help with, using the Chaos Engineering Engine in an experiment!

Uncover the Pitfall test driven

Since steadybit has already discovered our application, we can easily create some experiments to check the behavior. We will simulate the dropping of network packages for incoming and outgoing connections for Hotdeals. Just follow the next steps to create and run the experiment. If you have not yet installed and configured steadybit, request your demo to discuss next steps.

steadybit has discovered our system

Step 1: Create Infrastructure Experiment

First, you need to create and define a new experiment. When using steadybit this is quite simple:

  1. We go to experiments and select a new infrastructure experiment (because we deal with the network).
  2. We give the experiment a meaningful name (e.g. "Gateway's HTTP communication is robust") and choose the “Global” area (providing you full access to all discovered targets).
  3. We decide to attack containers and specify them with attributes. In the following screenshot you can see the query we used to narrow down the targets to the microservice Hotdeals.
Create experiment with steadybit, specifying targets
  1. Since we want to achieve a maximum effect, we choose an impact of 100% in the following step of the wizard.
  2. Apply the attack from the "network" category, "blackhole" to disrupt incoming and outgoing network connections. We can keep the default settings of the attack.
  3. We skip the "Execution and Monitoring" part for now and create the experiment by clicking on "Save experiment".

Step 2: Check System’s Behavior

Now it's time to check what we forgot in our implementation. Run the experiment you just created and see what happens in the application by checking the Network tab.

Discovered pitfall of missing HTTP request timeouts

Once the blackhole attack is running, the product list update is halted and remains in the pending state (last line). For the entire duration of the experiment (30 seconds), the request is neither resolved nor automatically cancelled. Why is this? At least there should be some timeouts, right?

Step 3: Fix the Pitfall

As mentioned earlier, Spring Boot already has many useful defaults that do not require additional configuration, but unfortunately they are missing some for timeout configurations of RestTemplate or RestTemplateBuilder. To fix this, we correct the initialization of the container's RestTemplate using the following code.

@Bean
public RestTemplate restTemplate() {
   return new RestTemplateBuilder()
           .setConnectTimeout(Duration.ofSeconds(2))
           .setReadTimeout(Duration.ofSeconds(2))
       .build();
}

Step 4: Verify the Fix

Verifying the new implementation by re-running the experiment shows that the application waits for the endpoint’s response for about 2 seconds and then terminates with an exception. This exception is caught and property handled, as we have also verified in an earlier blog post.

steadybit has discovered our system

Conclusion

In this blog post, we tested and improved the handling of a synchronous HTTP request under turbulent conditions. By using steadybit, we were able to prove that we cannot always rely on the default Spring Boot configurations and that we needed to adjust it. This verification was possible without having to change the source code or low-level networking. It also shows how important it is to think about turbulent conditions when testing your code - even when using widely established frameworks and reasonable conventions.

Written by

Manuel Gerding, Product Manager

Manuel is the youngster in the steadybit family and is constantly hungry for knowledge and new perspectives to broaden his horizons. After working almost a decade as a consultant and software engineer he focusses his perspective on the needs and demands of the user. His mission is to build a great product that really makes customer’s services more stable and valuable to their customers. To regain energy, Manuel loves to read a good book, take a trip with his bike or do a short meditation session.
@manuelgerding Manuel Gerding

Recent articles

  • How Healthy Are We? An Interview With Nora Jones – Founder and CEO of Jeli.io

    October is Mental Health Awareness Month. WHO wants to raise awareness of mental health issues around the world and mobilize efforts in support of mental health

    Read
  • Harden Performance of REST calls using Spring WebFlux

    Do you have sequential REST calls in your code? If so, how do they behave when the network is slow? Don't know yet? Let’s learn together and cover how easy we c

    Read
  • See metrics of your chaos experiments in steadybit with Prometheus

    If you run chaos experiments, you certainly want to see how these experiments play out in your monitoring tools - of course at the same time when you run the ex

    Read