Passing headers with Spring Cloud Feign

Feign is a great way to communicate between services and send data like a JSON request body, single header or multiple headers and much more. Spring Cloud has it’s own way of defining Feign clients, it’s done with Spring MVC annotations.

Usually it’s a common requirement that applications can localize messages. For localizing the messages, you might want to use your browser’s language, which is sent in the Accept-Language header.

Let’s consider the following structure for your application. One service which is called by the client, let’s call it test-app and one service which is called by the test-app service, let’s call it translator.

If you are communicating between test-app and translator with Feign, you will simply lose the original header information.

Fortunately, you can use Spring MVC annotations to pass the header to the translator service as a simple parameter.

Let’s see in practice, how you can implement this with Spring Boot.

One controller is needed for the translation service which looks the following:

@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
}

Of course, if it would be a real translation service, it should accept a message parameter as well and there are tons of other things to look out for if you are dealing with real translation, I just wanted to keep it simple for the sake of clarity.

The important thing here is that the controller method accepts a parameter which is coming from the Accept-Language HTTP header which we will pass with the Feign client on the app side.

On the app side, I have the Feign client in the following way:

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

As you can see, I used the very same Spring MVC annotation for passing the language header.

And here’s an example controller which triggers the functionality:

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

    @RequestMapping
    public TestResponse get(@RequestHeader("Accept-Language") String language) {
        MessageResponse messageResponse = client.message(language);
        String message = messageResponse.getMessage();
        return new TestResponse(message);
    }
}

class TestResponse {
    private String value;

    // getters/setters/constructor omitted
}

Also don’t forget the @EnableFeignClients annotation from the Application class.

Now if you start both services and open your favorite REST client (e.g. Postman) and trigger the URL http://localhost:9000/test and put the necessary header (i.e. Accept-Language: de-DE ) information into the request, you will get the localized message.

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.

3 Replies to “Passing headers with Spring Cloud Feign”

  1. Guangde Wang says:
    1. Herry says:
  2. Serhiy says:

Leave a Reply

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