HttpExchange vs OpenFeign - le match des clients HTTP
HttpExchange vs OpenFeign - le match des clients HTTP
Introduction
Quand on consomme des API dans un projet Spring Boot, on veut un client HTTP simple, testable et observable. Deux approches ressortent souvent :
@HttpExchange(Spring Framework) pour un client déclaré en interface, sans Spring Cloud- OpenFeign (Spring Cloud) pour un client déclaratif riche en intégrations
La question n’est pas “qui gagne”, mais dans quel contexte chaque solution brille. Un monolithe moderne n’a pas les mêmes besoins qu’un mesh de microservices, et un POC n’a pas les mêmes contraintes qu’une plateforme en production.
Objectif : comparer fonctionnellement, architecturalement et opérationnellement les deux options, avec du code vérifiable dans le repo.
Présentation d’OpenFeign
OpenFeign est un client HTTP déclaratif intégré à Spring Cloud. Il permet de définir une interface Java annotée et de déléguer le reste à l’infrastructure : sérialisation, erreurs, load-balancing, retries, discovery, configuration centralisée…
Petit point d’histoire
Feign est né dans l’écosystème Netflix OSS pour simplifier la communication entre services. Spring Cloud l’a intégré très tôt, ce qui en a fait un standard de facto dans les architectures microservices Spring.
Cas d’usage typiques
- Microservices avec discovery (
Eureka,Consul) et load-balancing - Besoin de configuration centralisée (timeouts, URLs, headers) via
Config Server - Équipes qui veulent générer les clients depuis OpenAPI et éviter les divergences
Pièges fréquents
- Trop lourd pour un service simple : si vous n’avez pas de Spring Cloud, Feign impose une stack inutile
- Surconfiguration : trop d’interceptors ou de retries peuvent masquer des problèmes réels
- Propagation des erreurs : mal gérée, elle peut faire passer une API instable pour “normale”
✅ Avantages / ❌ Inconvénients d’OpenFeign
| Avantages | Inconvénients |
|---|---|
| Intégration native Spring Cloud | Dépendance à Spring Cloud |
| Client déclaratif très concis | Stack plus lourde pour des projets simples |
| Génération automatique depuis OpenAPI | Moins de contrôle fin qu’un RestClient |
| Facilement extensible (interceptors, retries, encoders) | Courbe d’apprentissage si on ne connaît pas Spring Cloud |
| Très adapté aux microservices | Parfois surdimensionné pour un mono-service |
Présentation de HttpExchange
@HttpExchange est un mécanisme standard Spring Framework (sans Spring Cloud) qui permet de définir un client HTTP sous forme d’interface, puis de le brancher via un HttpServiceProxyFactory et un RestClient (ou WebClient).
Petit point d’histoire
Pendant longtemps, RestTemplate était la norme. Il a été remplacé par WebClient, puis par RestClient dans Spring Framework 6, plus simple et plus moderne. @HttpExchange vient compléter cette évolution en permettant une approche déclarative sans passer par Spring Cloud.
Cas d’usage typiques
- Monolithes modernes ou architectures “simple-to-deploy”
- Équipes qui veulent maîtriser la configuration HTTP (timeouts, codecs, auth, retry)
- Besoin d’un client léger, sans dépendances Cloud
Pièges fréquents
- Moins de “plug & play” : si vous avez besoin de discovery, LB, etc., vous devrez les ajouter vous-même
- Pas de génération OpenAPI native : il faut écrire les interfaces manuellement
- Risque de duplication : si plusieurs équipes écrivent leurs clients, attention aux incohérences
✅ Avantages / ❌ Inconvénients de HttpExchange
| Avantages | Inconvénients |
|---|---|
| Standard Spring Framework, sans Spring Cloud | Moins d’intégration microservices par défaut |
| Très léger, simple à activer | Pas de génération OpenAPI native |
Configuration fine via RestClient |
Plus de code “plomberie” à écrire |
| Parfait pour projets simples/modernes | Peut nécessiter des libs supplémentaires (résilience, retry) |
| Excellent pour du mono-service | Moins “plug & play” que Feign |
Tableau comparatif : OpenFeign vs HttpExchange
| Critère | OpenFeign | HttpExchange |
|---|---|---|
| Dépendances | Spring Cloud + Feign | Spring Framework uniquement |
| Mise en place | Très rapide si Cloud déjà en place | Très rapide, configuration minimale |
| Microservices | Excellent (discovery, LB, config) | Possible mais à assembler |
| Génération OpenAPI | Oui | Non |
| Observabilité | Cloud + Micrometer prêts | Via RestClient/WebClient + Micrometer |
| Résilience | Facile via Cloud | À ajouter (Resilience4j, etc.) |
| Contrôle fin HTTP | Moyen | Élevé |
| Courbe d’apprentissage | Facile pour équipes Cloud | Facile pour équipes Spring |
Performances et observabilité
Performances
- OpenFeign ajoute une couche d’abstraction supplémentaire, mais en pratique la différence est souvent négligeable comparée à la latence réseau. Le vrai impact vient du nombre d’appels, des retries et des timeouts mal réglés.
- HttpExchange repose directement sur
RestClient/WebClient. Moins de couches = latence marginalement plus faible et plus de contrôle.
Le vrai levier de performance ne vient pas du choix du client, mais de :
- la réduction du nombre d’appels
- le caching côté client
- les timeouts bien ajustés
- la résilience bien paramétrée pour éviter les avalanches de retries
Observabilité
- Avec OpenFeign, les métriques et traces s’intègrent facilement si vous utilisez Spring Cloud + Micrometer.
- Avec HttpExchange, vous devez brancher vos interceptors ou configurer
RestClientpour exposer les mêmes métriques.
Dans les deux cas, le point clé reste de rendre visibles :
- temps de réponse
- taux d’erreur
- volume par endpoint
Si votre équipe a déjà une pile observabilité bien rodée, Feign s’insère plus naturellement. Sinon, HttpExchange vous donne un meilleur contrôle mais demande un peu plus d’effort.
Quand choisir l’un ou l’autre ?
Choisir OpenFeign si :
- vous êtes déjà dans Spring Cloud
- vous générez vos clients depuis OpenAPI
- vous exploitez Config Server, Discovery, load balancing
- vous voulez un client immédiatement “cloud-ready”
Choisir HttpExchange si :
- vous voulez un client léger et moderne
- votre contexte est mono-service ou simple
- vous préférez contrôler les configurations HTTP
- vous ne voulez pas dépendre de Spring Cloud
Exemple par le code (repo)
Dans le repo springboot-demo, le module de test est :
developer-tools/code-generation-tutorial/client-generation-tutorial
Il contient deux apps :
BookApplication(API de livres) surhttp://localhost:8092AuthorApplication(consommateur)
Dans AuthorApplication, on a :
- le client Feign généré via OpenAPI
- un client HttpExchange déclaré manuellement
- une abstraction
BookClientpour basculer facilement
1) Client HttpExchange
@HttpExchange
public interface BookHttpExchangeClient {
@GetExchange("/books/author/{id}")
List<Book> getBooksByAuthorId(@PathVariable("id") Long authorId);
@PostExchange("/books")
Book createBook(@RequestBody Book book);
}
2) Configuration via RestClient
@Bean
public BookHttpExchangeClient bookHttpExchangeClient(
@Value("${bookManagement.url:http://localhost:8092}") String bookManagementUrl
) {
RestClient restClient = RestClient.builder()
.baseUrl(bookManagementUrl)
.build();
HttpServiceProxyFactory factory = HttpServiceProxyFactory
.builderFor(RestClientAdapter.create(restClient))
.build();
return factory.createClient(BookHttpExchangeClient.class);
}
3) Adapter Feign (client généré)
@Service
@ConditionalOnProperty(name = "books.client", havingValue = "feign", matchIfMissing = true)
public class FeignBookClientAdapter implements BookClient {
private final BookManagementApi bookManagementApi;
public FeignBookClientAdapter(BookManagementApi bookManagementApi) {
this.bookManagementApi = bookManagementApi;
}
@Override
public List<Book> getBooksByAuthorId(Long authorId) {
return bookManagementApi.getBooksByAuthorId(authorId);
}
@Override
public Book createBook(Book book) {
return bookManagementApi.createBook(book);
}
}
4) Basculer par propriété
books.client=feign
# ou
books.client=http-exchange
Résultat : les endpoints REST de AuthorApplication restent inchangés, seule la stratégie d’appel change.
Conclusion
Le bon choix ne dépend pas de “qui gagne”, mais du contexte.
- OpenFeign reste l’option la plus naturelle pour un environnement Spring Cloud, surtout si vous générez vos clients depuis OpenAPI.
- HttpExchange est idéal quand on veut un client moderne, léger, et totalement maîtrisé.
Dans tous les cas, les deux approches sont valides, modernes et compatibles avec Spring Boot 3.x.
Liens utiles dans le vault
- générer des clients depuis OpenAPI : Générer vos clients d’API à partir de leur spécification OpenAPI
- gérer les erreurs correctement : Vers un standard des erreurs HTTP
- résilience : Résilience applicative avec Resilience4j et Spring Boot