spring-mvcspring-webfluxnetflix-eurekaspring-webclientspring-cloud-feign

Using Spring HTTP Interfaces for Internal Service Calls via Eureka Service Registry


How can Spring HTTP Interfaces be utilized to make internal service calls via a eureka service registry?

As of the Spring Cloud 2022.0.0 release, the Spring Cloud OpenFeign project is considered feature-complete. Future updates will focus on bug fixes and minor community contributions. Users are encouraged to migrate to Spring Interface Clients for continued development and support.


Solution

  • discover the services by service name from eureka service registry using Spring HTTP Interfaces to make internal services calls.

            import org.springframework.cloud.client.loadbalancer.reactive.LoadBalancedExchangeFilterFunction;
            import org.springframework.context.annotation.Bean;
            import org.springframework.context.annotation.Configuration;
            import org.springframework.web.bind.annotation.RequestBody;
            import org.springframework.web.reactive.function.client.WebClient;
            import org.springframework.web.reactive.function.client.support.WebClientAdapter;
            import org.springframework.web.service.annotation.HttpExchange;
            import org.springframework.web.service.annotation.PostExchange;
            import org.springframework.web.service.invoker.HttpServiceProxyFactory;
            import reactor.core.publisher.Mono;
            
            @Configuration
            public class HttpInterfacesConfig {
            
                @HttpExchange("/root")
                public interface SampleServiceClient {
            
                    @PostExchange("/test")
                    Mono<String> testEndpoint(@RequestBody Mono<String> logRequestMono);
                }
            
                @Bean
                public SampleServiceClient sampleServiceClient(LoadBalancedExchangeFilterFunction lbef, WebClient.Builder wcb) {
            
                    WebClient webClient = wcb.baseUrl("http://your-service-name")// your service name here
                            .filter(lbef)
                            //.defaultHeaders(headers -> headers.add("Authorization", "Basic your-auth-token-here")) if you have security use this
                            .build();
                    WebClientAdapter adapter =  WebClientAdapter.create(webClient);
                    HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();
                    return factory.createClient(SampleServiceClient.class);
                }
            }
    

    use above HttpInterfacesConfig.SampleServiceClient to make call to other service

    @Component
    @RequiredArgsConstructor
    public class Test {
    
            private final HttpInterfacesConfig.SampleServiceClient sampleServiceClient;
            
            Mono<String> callOtherService(Mono<String> logRequestMono) {
                
                return sampleServiceClient.testEndpoint(logRequestMono);
            }
    }