7.4 Inter-Service Communication: OpenFeign & WebClient
← Back to Chapter 7: Microservices & Spring Cloud
Synchronous communication between microservices can be achieved via declarative HTTP clients (Spring Cloud OpenFeign) or non-blocking reactive clients (Spring WebClient).
1. Spring Cloud OpenFeign (Declarative REST Client)
OpenFeign allows you to define an interface annotated with standard Spring MVC annotations. Spring automatically generates the underlying HTTP client implementation at runtime!
1. Enable Feign Clients
@SpringBootApplication
@EnableFeignClients
public class OrderApplication { ... }
2. Define the Feign Interface
// 'name' maps to the registered Eureka service name!
@FeignClient(name = "payment-service", path = "/api/v1/payments", configuration = FeignClientConfig.class)
public interface PaymentServiceClient {
@PostMapping("/process")
PaymentResponse processPayment(@RequestBody PaymentRequest request);
@GetMapping("/{transactionId}")
PaymentDetails getPaymentDetails(@PathVariable("transactionId") UUID transactionId);
}
3. Propagating Headers via RequestInterceptor
Pass auth tokens and correlation IDs to downstream services automatically:
@Configuration
public class FeignClientConfig {
@Bean
public RequestInterceptor bearerAuthRequestInterceptor() {
return requestTemplate -> {
String token = SecurityContextHolder.getContext().getAuthentication().getCredentials().toString();
requestTemplate.header("Authorization", "Bearer " + token);
requestTemplate.header("X-Correlation-Id", MDC.get("correlationId"));
};
}
}
2. Spring WebClient (Non-Blocking & Reactive)
WebClient (from spring-boot-starter-webflux) is the modern replacement for legacy RestTemplate, supporting both asynchronous reactive streams and synchronous .block() execution.
@Service
public class InventoryClient {
private final WebClient webClient;
public InventoryClient(WebClient.Builder builder) {
this.webClient = builder.baseUrl("http://inventory-service").build();
}
public Mono<InventoryResponse> checkStock(String sku) {
return webClient.get()
.uri("/api/v1/inventory/{sku}", sku)
.retrieve()
.bodyToMono(InventoryResponse.class)
.timeout(Duration.ofMillis(1500));
}
}
3. Comparison: RestTemplate vs OpenFeign vs WebClient
| Feature | RestTemplate | OpenFeign | WebClient |
|---|---|---|---|
| Paradigm | Blocking (Synchronous) | Blocking (Synchronous) | Non-blocking (Reactive) & Blocking |
| API Style | Programmatic template | Declarative Interface | Fluent Functional Builder |
| Recommendation | Maintenance mode | Excellent for standard microservices | Modern default for high throughput |