'Override URL and Authentication configuration of Spring Cloud Feign client

I am trying to leverage Spring Cloud Feign client for declaring rest endpoints(third-party-endpoints) which will be called based on the request that my controller receives.

I have declared a feign client interface like:

    @FeignClient(name = "my-client", url = "https://abc.xyz.com", configuration = MyClientConfiguration.class)
    public interface MyFeignClient{
}

MyClientConfiguration is an unannotated feign configuration class just exposing BasicAuthRequestInterceptor bean preconfigured with some credential.

public class MyClientConfiguration {
   
    @Bean
    public BasicAuthRequestInterceptor basicAuthRequestInterceptor(){
        return new BasicAuthRequestInterceptor("USERID","PWD");
    }

}

So, what I have right now is a preconfigured feign client.

I am not sure how do I deal with the requirement that asks for being able to define/override the feign configuration with the url and credentials received in the body of different POST request.

So its not about overriding the feign configuration via properties file(like other somewhat similar SO questions), but instead being able to configure the feign client on the fly based on the url and credentials received in the body of the incoming requests.

I am aware of ways to do it with WebClient and looking for something similar to what WebClient provides via its uri and headers methods. Webclient allows us to override the webClient bean configuration with different uri and different auth credentials,

        webClient
                .put()
                .uri("base-uri", uriBuilder -> uriBuilder.path("/rest").path("/api").path("/2").path("/issue").path("/" + id).build())
                .headers(httpHeaders -> {
                    httpHeaders.setBasicAuth("decrypted-username", "decrypted-pwd");
                })

Does Spring Cloud Feign provide any such facility where it is possible to have a generic configuration yet allowing to override those configurations at runtime?

EDIT 1 : START

The closest I got to is implementing via the feign's builder pattern :

    MyFeignClient myFeignClient = Feign.builder()
            .contract(new SpringMvcContract())
            .requestInterceptor(new BasicAuthRequestInterceptor("decrypted-username", "decrypted-pwd")
            .target(MyFeignClient.class, myRequestDTO.getBaseUrl());

I was challenged with an exception because I didn't specify which Contract to use. It was using the Default Contract.I then changed to SpringMvcContract as the annotation that I am using are the Spring MVC ones and not feign's default.

Getting DecodeException as of now. Trying to fix it. Will post update when done.

EDIT 1 : END

EDIT 2 : START

I was finally able to get this working. I figured out that the feign-gson does a great job at deserialization with minimal configuration. My final feign configuration with the Decoder in place looks like :

MyFeignClient myFeignClient = Feign.builder()
                .contract(new SpringMvcContract())
                .decoder(new GsonDecoder())
                .requestInterceptor(new BasicAuthRequestInterceptor("decrypted-username", "decrypted-pwd")
                        .target(MyFeignClient.class, myRequestDTO.getBaseUrl());

EDIT 2 : END



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source