Newbie
Newbie

Reputation: 7249

How to exclude RequestInterceptor for an specific Spring Cloud Feign client?

I have a number of clients for which a "global" RequestInterceptor has been defined. For one of the clients I need this "global" interceptor to be excluded. Is it possible to override the full set of RequestInterceptors for a particular FeignClient?

@FeignClient(value = "foo", configuration = FooClientConfig.class)
public interface FooClient {
//operations
}

@Configuration
public class FooClientConfig{

//How do I exclude global interceptors from this client configuration?
}

The spring-cloud-netflix version in use is 1.1.0 M5

Upvotes: 10

Views: 13288

Answers (4)

luckystones
luckystones

Reputation: 371

Based on the issue stated here. Instead of excluding interceptors, you need to define different feign clients for each API. Add your interceptors based on your needs.

public class ConfigOne {
  @Bean
  public InterceptorOne interceptorOne(AdditionalDependency ad) {
    return new InterceptorOne(ad);
  }
}

Just make sure you don't use @Configuration annotation on above class. Instead, importing this bean on client definition would be a working solution.

@FeignClient(name = "clientOne", configuration = ConfigOne.class)
public interface ClientOne { ... }

Upvotes: 3

Yashasvi.G
Yashasvi.G

Reputation: 41

One way to do this to remove the @Configuration annotation from the FooClientConfig class as in the current situation it is applied globally.

And then use

@FeignClient(value = "foo", configuration = FooClientConfig.class)

on all of the feign clients you want to use the config with.

Upvotes: 0

Bahadir Tasdemir
Bahadir Tasdemir

Reputation: 10793

An enhanced way of solving this is to pass a custom header to your request like:

@PostMapping("post-path")
ResponseEntity<Void> postRequest(@RequestHeader(HEADER_CLIENT_NAME) String feignClientName, @RequestBody RequestBody requestBody);

I want to set the header in interceptor for only this feign client. Before setting the header, first, the interceptor checks HEADER_CLIENT_NAME header if exists and have the desired value:

private boolean criteriaMatches(RequestTemplate requestTemplate) {
    Map<String, Collection<String>> headers = requestTemplate.headers();
    return headers.containsKey(HEADER_CLIENT_NAME)
        && headers.get(HEADER_CLIENT_NAME).contains("feign-client-name");
}

Thus, you can check before setting the basic authentication. In interceptor:

@Override
public void apply(RequestTemplate template) {
    if (criteriaMatches(template)) {
        /*apply auth header*/
    }
}

In this way, other feign client's requests won't be manipulated by this interceptor.

Finally, I set the feignClientName to the request:

feignClient.postRequest("feign-client-name", postBody);

Upvotes: 0

fungbo
fungbo

Reputation: 31

It seems there is no easy way to override the global interceptor. I think you could do it like this:

@Configuration
public class FooClientConfig{

@Bean
RequestInterceptor globalRequestInterceptor() {
    return template -> {
        if (template.url().equals("/your_specific_url")) {
            //don't add global header for the specific url
            return;
        }

        //add header for the rest of requests
        template.header(AUTHORIZATION, String.format("Bearer %s", token));
    };
}
}

Upvotes: 3

Related Questions