2 years ago

#17431

test-img

dinvlad

Auto-forward RestController request header(s) to all RestTemplate requests

Consider users sending requests to service A, which then implements business logic that includes submitting multiple requests to services B, C etc.

Service A is implemented using a RestController, which receives certain headers (e.g. Authorization) from users.

Service A then submits requests to services B, C etc. using a RestTemplate bean.

How does one make it automatically forward service A RestController headers with any requests submitted via the RestTemplate bean to services B, C etc.?

The goal here is to avoid specifying these headers explicitly on every RestTemplate request. The ultimate goals are:

  1. Enable a zero-trust microservice architecture, where all requests between internal services are authenticated.
  2. Preserve authenticated user context for all requests from (1).
  3. Do it with the least amount of change possible.

I've heard recommendations using Zuul or similar proxies for such things, but wanted to confirm if this is the best/most common/suitable approach for this particular scenario. What makes me pause on it is that service A is not a simple "proxy" service that just forwards requests on different routes, but rather a rich REST API that needs to "use" other services, rather than simply forward/enrich incoming requests. So I'm not sure if Zuul or other proxies would be fully suitable for it.

To make it a bit more concrete, I'd like to avoid having to modify logic like this:

    @GetMapping("/baz")
    public Baz getBaz() {
        final Foo foo = restTemplate.getForObject("http://service-b/foo", Foo.class)
        final Bar bar = restTemplate.getForObject("http://service-c/bar/{barId}", Bar.class, foo.getBarId());
        return bar.getBaz();
    }

While one could replace restTemplate.getForObject(...) with: restTemplate.exchange(url, HttpMethod.GET, new HttpEntity<>(req.getHeaders()), Response.class, param), doing so is undesirable for services with many API calls.

Alternatively, doing so via a ClientHttpRequestInterceptor would only be possible if were able to access GetMapping's per-request header inside the interceptor.

Any concrete examples would be much appreciated!

Update: I may have found answers to similar questions here and here. Looks like the missing pieces have been RequestContextHolder.currentRequestAttributes() for MVC and subscriberContext for WebFlux.

spring

spring-boot

netflix-zuul

0 Answers

Your Answer

Accepted video resources