Why Spring Is Dropping Feign: A Deep Dive into @HttpExchange vs Feign
This article analyzes why Spring Framework introduced the native @HttpExchange HTTP client to replace OpenFeign, comparing their architectures, dependencies, proxy mechanisms, performance benchmarks, and offering migration guidance for developers deciding between the two declarative HTTP solutions.
Introduction
Spring Cloud’s OpenFeign has been the de‑facto declarative HTTP client for microservices for nearly a decade. With Spring Framework 6, Spring introduced a native solution called HTTP Interface whose core annotation is @HttpExchange. The article explains why Spring is encouraging developers to move from Feign to this new approach.
What the Two Solutions Are
Feign is a Netflix‑originated library that lives in the Spring Cloud ecosystem. It requires the spring-cloud-starter-openfeign dependency and works via JDK dynamic proxies.
@HttpExchange is part of Spring Framework itself, needs no extra Spring Cloud components, and uses HttpServiceProxyFactory to create proxies.
Code Comparison
Feign client definition:
@FeignClient(name = "user-service", url = "${user.service.url}")
public interface UserClient {
@GetMapping("/users/{id}")
User getUserById(@PathVariable("id") Long id);
@PostMapping("/users")
User createUser(@RequestBody User user);
@GetMapping("/users")
List<User> getUsers(@RequestParam("page") int page, @RequestParam("size") int size);
}Corresponding @HttpExchange client:
@HttpExchange("http://localhost:8080/api/v1")
public interface UserClient {
@GetExchange("/users/{id}")
User getUserById(@PathVariable Long id);
@PostExchange("/users")
User createUser(@RequestBody User user);
@GetExchange("/users")
List<User> getUsers(@RequestParam int page, @RequestParam int size);
}To enable @HttpExchange, a HttpServiceProxyFactory bean must be defined:
@Configuration
public class HttpClientConfig {
@Bean
public UserClient userClient(RestClient restClient) {
RestClientAdapter adapter = RestClientAdapter.create(restClient);
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();
return factory.createClient(UserClient.class);
}
}Dependency and Configuration Differences
Feign requires the spring-cloud-starter-openfeign dependency and @EnableFeignClients.
@HttpExchange has no extra dependencies; it is built into Spring Framework 6+.
Feign’s annotation names differ ( @FeignClient, @GetMapping) whereas @HttpExchange uses @HttpExchange, @GetExchange, @PostExchange.
Proxy Mechanisms
Feign generates a JDK dynamic proxy that builds HTTP requests and sends them via Apache HttpClient, OkHttp, or HttpURLConnection. It integrates tightly with Spring Cloud’s LoadBalancerClient for service discovery.
@HttpExchange creates a proxy through HttpServiceProxyFactory. The underlying client is chosen automatically: synchronous calls use RestClient, while reactive return types ( Mono, Flux, CompletableFuture) trigger WebClient. This design cleanly separates interface definition from execution details.
Performance Comparison
Benchmark under 1,000 concurrent requests shows:
Throughput: @HttpExchange delivers roughly +40 % higher throughput than OpenFeign.
Memory usage: @HttpExchange consumes about 35 % less memory.
Pros and Cons
Feign
Mature ecosystem, rich extensions, and deep Spring Cloud integration.
High developer familiarity.
Simple configuration (just declare an interface).
Drawbacks: heavyweight Spring Cloud dependency, blocking I/O, not reactive, version alignment required with Spring Cloud.
@HttpExchange
Native to Spring Framework, no extra dependencies.
Supports both blocking and reactive programming models.
Better performance and lower resource consumption.
Drawbacks: newer ecosystem, fewer third‑party extensions, slightly more boilerplate for proxy factory (simplified in Spring 7 with @ImportHttpServices), and lower team familiarity.
Migration Guidance
For teams planning to switch:
New interfaces: write them directly with @HttpExchange.
Low‑traffic Feign clients: gradually replace with @HttpExchange.
High‑traffic core clients: migrate after the team is comfortable with the new API.
Future simplification: adopt Spring 7’s @ImportHttpServices to remove manual factory configuration.
When to Keep Feign
Existing large codebases with many Feign interfaces.
Projects that rely heavily on Spring Cloud features such as service discovery and circuit breaking.
Teams with strong Feign expertise and no need for reactive support.
When to Adopt @HttpExchange
New projects that want a lightweight, native solution.
Applications that require reactive programming (WebFlux) or high concurrency.
Scenarios where minimizing dependencies and improving performance are priorities.
Conclusion
Spring is not discarding Feign because它 is bad; rather, the ecosystem has evolved. @HttpExchange offers a lighter, more flexible, and natively supported alternative that aligns with modern reactive and high‑performance requirements. Teams should evaluate their current architecture, performance needs, and migration cost to decide which client best fits their future development.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
IT Services Circle
Delivering cutting-edge internet insights and practical learning resources. We're a passionate and principled IT media platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
