0

I'm currently trying to write a Spring Boot starter that would automatically authenticate our microservices with an API gateway and include the access token in the headers for all outgoing requests (towards the gateway).
I'm creating a RestTemplate bean and giving it our custom interceptor, but my problem is, by doing this, I prevent other teams (who would be using this starter) to use their own RestTemplate config, since they would have to define the same bean leading to multiple beans existing.

@Bean public RestTemplate restTemplate(){ RestTemplate restTemplate = new RestTemplate(); List<ClientHttpRequestInterceptor> interceptors = restTemplate.getInterceptors(); if (interceptors.isEmpty()){ interceptors = new ArrayList<>(); } interceptors.add(clientCredentialsAuthInterceptor()); restTemplate.setInterceptors(interceptors); return restTemplate; } 

Is there another way of intercepting all outgoing requests or make the RestTemplate further configurable?

1
  • Ideally your projects should use the RestTemplateBuilder to create instances of a RestTEmplate this in turn will auto detect all pre-registered interceptors. The only thing your autp-config has to do is make a bean for the interceptor. Or define a RestTemplateCustomizer which adds the interceptor. However this only works if teams follow the practice of using the RestTemplateBuilder to create instances. Commented Dec 10, 2020 at 15:39

1 Answer 1

0

Not tested but it may give you a start point:

// Create an interface that users of your dependency // can implement which provides interceptors public interface RestTemplateAuthInterceptorProvider { // This interface provides interceptors, so they can add as many as they want List<ClientHttpRequestInterceptor> provideInterceptor(); } import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; // define a conditional default implementation of your interceptor provider @Bean @ConditionalOnMissingBean(RestTemplateAuthInterceptorProvider.class) public RestTemplateAuthInterceptorProvider restTemplateAuthInterceptorProvider() { return () -> ... // implement your auth interceptor and return } // In your actual rest template creation use method argument injection // If other teams implement the RestTemplateAuthInterceptorProvider interface // conditional case above will be false and your implementation will not interfere // If they dont implement RestTemplateAuthInterceptorProvider // your default implementation will be here @Bean public RestTemplate restTemplate(RestTemplateAuthInterceptorProvider provider) { RestTemplate restTemplate = new RestTemplate(); List<ClientHttpRequestInterceptor> interceptors = restTemplate.getInterceptors(); if (interceptors == null){ interceptors = new ArrayList<>(); } interceptors.addAll(provider.provideInterceptor()); // from argument restTemplate.setInterceptors(interceptors); return restTemplate; } 

Edit: Another hacky approach is to manipulate already defined RestTemplate beans

@Component @ConditionalOnBean(RestTemplate.class) public class RestTemplateBeanCustomizer { private List<RestTemplate> restTemplateBeans; // This injects all restTemplate bean definitions to your bean as a list @Autowired public RestTemplateBeanCustomizer(List<RestTemplate> restTemplateBeans) { this.restTemplateBeans = restTemplateBeans; } @PostConstruct public void customizeRestTemplateBeans() { for (RestTemplate restTemplate : restTemplateBeans) { // Add your interceptors message handlers etc // restTemplate.set... } } } 
Sign up to request clarification or add additional context in comments.

1 Comment

This would only allow them to define their custom interceptors, if I'm correct. My question is more about creating the RestTemplate itself. Let's say they want to add a custom messageHandler to it, but the starter already defined a bean without that. I could annotate it with @ConditionalOnMissingBean, but then if someone defines it, it wouldn't have the interceptor set.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.