Search code examples
spring-cloudspring-cloud-netflixnetflix-feignspring-cloud-feignfeign

How to pass any number of headers to Feign client without knowing all the names?


I've a use case where I need to pass all headers that start with a certain prefix to the feign client. I don't know the number or exact names of these headers. There doesn't seem to be a way to to do this easily as the Feign client expects all headers to be specified using @RequestHeader("name"). It doesn't seem to support something like @RequestHeader HttpHeaders, which would be very useful. Any suggestions?


Solution

  • As of this writing, Feign doesn't support dynamic headers or query parameters using a Map. The Spring Cloud Feign client relies on the Spring annotations instead of Feign annotations, and the implementations of AnnotatedParameterProcessor have a bug such that they don't do what the documentation states they should be doing.

    RequestHeader doc:

    If the method parameter is Map, MultiValueMap, or HttpHeaders then the map is populated with all header names and values.

    RequestParam doc:

    If the method parameter is Map or MultiValueMap and a parameter name is not specified, then the map parameter is populated with all request parameter names and values.

    I submitted a pull request that will fix this. Until then, I'm using an extension of SpringMvcContract that uses my own AnnotatedParameterProcessor implementations. I set the custom SpringMvcContract using a Feign.Builder as follows:

    @Autowired
    FormattingConversionService feignConversionService;
    
    @Bean
    @Scope(SCOPE_PROTOTYPE)
    public Feign.Builder feignBuilder() {
        return HystrixFeign.builder()
                .contract(feignContract());
    }
    
    @Bean
    public Contract feignContract() {
        return new EnhancedSpringMvcContract(feignConversionService);
    }