Spring Boot does not provide auto-configured RestTemplate bean

Spring Boot does not provide auto-configured RestTemplate bean

Background

This started off when my colleague asked me why, when defined with our own RestTemplate Bean, there is no need to use @Qualifier to injecting the bean into the class.

Imagine the following code

@Configuration
public class WebConfig {
    @Bean
    public RestTemplate myRestTemplate() {
        return new RestTemplate();
    }
}

@Service
@RequiredArgsConstructor
public class PokemonAPI {
    // @Qualifier("myRestTemplate") -- not required
    private final RestTemplate restTemplate;
}
  1. We declared a RestTemplate bean in WebConfig class, with name as myRestTemplate
  2. We injected the RestTemplate into PokemonAPI class without using @Qualifier

I stumbled for a while, and I couldn't think any reasonable answer at that time. Why is that so?

Assumption

My initial assumption was actually the cause of the misunderstanding. Since we are dealing with Spring Boot, I automatically assume that a default auto-configured RestTemplate bean must have been provided. Hence, if I also initialize my own RestTemplate as shown above, there would have been 2 different RestTemplate bean. I couldn't have been more wrong.

Thinking back, even if that is the case, there wouldn't have been 2 different beans because Spring Boot is known to backoff when there is a bean defined manually. Therefore, there should only have a single bean even if we declared RestTemplate bean in the WebConfig class.

This is a sign of rusty knowledge of core Spring / Spring Boot.

Finding Answers

Determined to search for the answer, I wrote some code and attempt to find out why. I know that this is something basic, but I just couldn't figure out at that point of time.

I had this code

@Configuration
public class WebConfig {
    @Bean
    public RestTemplate myRestTemplate() {
        return new RestTemplate();
    }
}

@RequiredArgsConstructor
public class PokemonAPI {
    private static final String POKE_URL = "https://pokeapi.co/api/v2/pokemon/{name}";
    private final RestTemplate restTemplate;

    public Pokemon get(String name) {
        return restTemplate.exchange(POKE_URL, HttpMethod.GET, null, Pokemon.class, name).getBody();
    }
}

And I never once thought to not configure a self defined RestTemplate bean to test it out for some reason.

Auto Backoff

As mentioned previously, I should have thought of this point earlier because this might give me a hint earlier to look elsewhere. At the back of my mind, I am convinced that there should have 2 beans, so why the heck @Qualifier is not required?

No auto-configured RestTemplate

Unable to figure out, I turned to Twitter and Stéphane Nicoll was kind enough to point me to the docs, and that's when I know (I never knew this before) Spring does not provide auto-configured RestTemplate bean which, as mentioned, was the basis of my assumption initially.

Once again, this proves that we should always look at the official doc first. RTFM anyone?

Since RestTemplate instances often need to be customized before being used, Spring Boot does not provide any single auto-configured RestTemplate bean

Conclusion

Since there is only a single instance of RestTemplate bean configured, naturally, there is no need for @Qualifier and Spring can inject RestTemplate just fine using byType autowiring. And always RTFM first!

Tips

This is not the focus of this post but I thought I should mentioned this, as far as possible, we should use RestTemplateBuilder to initialize RestTemplate instance which is also mentioned in the docs

It does, however, auto-configure a RestTemplateBuilder, which can be used to create RestTemplate instances when needed. The auto-configured RestTemplateBuilder ensures that sensible HttpMessageConverters are applied to RestTemplate instances.

Source Code

Full source code is available in GitHub