Customizing each request with Spring Cloud Feign interceptor

Recently I wrote an article  how to explicitly pass headers via Feign clients. Now I’ll show you how to customize each request sent via Feign clients, like adding headers to all of them without the need to explicitly define them using Feign interceptors.

Let’s see the previous example, a translator and a test application.

The client calls the test-app and then it calls to the translator and the translator does the job according to the original Accept-Language  header sent by the client.

Let’s see the translator application’s code, it has a single controller:

@RestController("/message")
public class TranslationController {
    @RequestMapping
    public MessageResponse message(@RequestHeader(value = "Accept-Language") String language) {
        String message = "english";
        if (Locale.GERMANY.equals(Locale.forLanguageTag(language))) {
            message = "german";
        }
        return new MessageResponse(message);
    }
}

class MessageResponse {
    private String message;

    // getters/setters/constructor omitted
}

Simple. Okay let’s see the test-app’s code. The controller which the client can trigger:

@RestController("/test")
public class TestController {
    @Autowired
    private TranslationClient client;

    @RequestMapping
    public TestResponse get() {
        MessageResponse messageResponse = client.message();
        String message = messageResponse.getMessage();
        return new TestResponse(message);
    }
}

class TestResponse {
    private String value;

    // getters/setters/constructor omitted
}

TranslationClient  is the Feign client:

@FeignClient(name = "translation", url = "http://localhost:9001")
public interface TranslationClient {
    @RequestMapping("/message")
    MessageResponse message();
}

As you can see there is no RequestHeader  parameter defined for the method so how can we pass the header information?

Feign has a so called RequestInterceptor  which will be applied for all the requests sent by Feign clients. The only thing that’s necessary is to define a custom RequestInterceptor class and register it as a Spring bean. Let’s see how it looks:

@Component
public class LanguageRequestInterceptor implements RequestInterceptor {
    private static final String ACCEPT_LANGUAGE_HEADER = "Accept-Language";

    @Override
    public void apply(RequestTemplate requestTemplate) {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (requestAttributes == null) {
            return;
        }
        HttpServletRequest request = requestAttributes.getRequest();
        if (request == null) {
            return;
        }
        String language = request.getHeader(ACCEPT_LANGUAGE_HEADER);
        if (language == null) {
            return;
        }
        requestTemplate.header(ACCEPT_LANGUAGE_HEADER, language);
    }
}

So the important thing here is to first get the header information from the incoming HTTP request. This can be done using the RequestContextHolder#getRequestAttributes which is holding the current request information. After we got the original request, extracting the Accept-Language  header is not a complicated thing to do. Then simply using the RequestTemplate , the header can be set for the Feign requests.

Marking the class with @Component  will define it as a Spring bean and we are done.

Now if we try to invoke the test-app from your favorite REST client with the Accept-Language  header with value de-DE , you will see the german text coming back in the response.

Using this example, you can customize your requests in any way you like.

The code can be found on my GitHub page. If you are interested in more topics, make sure you follow me on Twitter and shout out if you have questions.

One Reply to “Customizing each request with Spring Cloud Feign interceptor”

  1. Anoop says:

Leave a Reply

Your email address will not be published. Required fields are marked *