Aller au contenu

Spring WebFlux #1 : Introduction à la stack réactive de Spring

Et si vos APIs pouvaient gérer des milliers de connexions simultanées sans saturer vos serveurs ? Spring WebFlux vous montre comment rendre vos applications plus réactives et performantes.

Photo by [Robin Pierre](https://unsplash.com/fr/@robinpierre) / [Unsplash](https://unsplash.com/fr)
Photo by Robin Pierre / Unsplash

La philosophie de WebFlux 💡

WebFlux est asynchrone, non bloquant et repose sur une idée simple, mais puissante : "Au lieu de bloquer un thread quand on attend une réponse, continuons à traiter d'autres requêtes".

Cette approche change profondément la manière dont une application Spring gère ses requêtes.

Traditionnellement, avec Spring MVC, chaque requête HTTP est prise en charge par un thread dédié. Le thread est alors alloué à la requête et reste occupé pendant tout le traitement, même lorsqu'il attend une réponse d'une base de données ou d'un service externe.

De ce fait, lorsque le nombre de requêtes HTTP augmente en simultané, le serveur va alors devoir créer et maintenir de nombreux threads, ce qui va consommer énormément de mémoire et provoquer des lenteurs dans l'application.

WebFlux va permettre d'amortir la charge et gérer les threads de manière beaucoup plus efficiente.

Un modèle non bloquant et asynchrone 🔄

WebFlux utilise un event loop (boucle d'événement), similaire à ce que fait Node.js ou Netty, sur laquelle il s'appuie d'ailleurs.

Au lieu d'affecter un thread à chaque requête, le framework s'appuie sur un nombre de threads restreint, capables de gérer des milliers d'évènements concurrents.

Lorsqu'une requête attend une réponse, le thread est alors libéré et peut s'occuper d'autres traitements. Lorsque la réponse arrive, un nouvel évènement est déclenché dans l'event loop, et le traitement reprend là où il s'était arrêté.

C'est cette capacité à ne jamais "gaspiller" un thread en attente qui rend WebFlux très efficace dans les environnements à forte charge.

Un exemple concret : la salle de restauration 🍴

On peut représenter la programmation réactive avec WebFlux avec une grande salle de restaurant.

Dans un modèle classique (Spring MVC), un serveur est affecté à une seule table du début à la fin du repas. Il prend la commande, sert le plat, encaisse et débarrasse la table. Entre chaque étape, le serveur attend.

Si le restaurant est très fréquenté, il faut engager beaucoup de serveurs, ce qui coûte cher et limite l'efficacité.

Avec WebFlux, la logique change.

Les serveurs deviennent polyvalents et rapides. Pendant qu'une table attend son plat, ils se déplacent pour s'occuper d'autres tables, prendre de nouvelles commandes, encaisser d'autres clients... Lorsque le plat est prêt, le serveur revient à la table initiale et poursuit le service.

Cette approche illustre la philosophie de WebFlux :

  • Peu de threads gèrent de nombreuses requêtes
  • Aucune attente bloquante
  • Le flux de traitement reste continu et fluide, même avec une forte charge.

La programmation réactive : penser en "flux" 🌊

C'est une approche inspirée du modèle asynchrone et déclaratif.

On va alors orchestrer les méthodes pour expliquer au code comment réagir quand la donnée sera disponible.

Cela permet de composer facilement une suite d'opérations sans bloquer le traitement. Ces opérations seront alors traitées une fois la donnée prête, sans jamais attendre de manière synchrone.

Cette approche ne se limite pas à la technique, elle impose également un changement de manière de penser.

On passe alors d'un mode impératif ("Traite cette donnée, puis fais en ceci, et enfin cela.") à un modèle déclaratif et réactif ("Lorsque le traitement de cette donnée sera terminé, utilise le résultat pour faire ceci, puis cela".).

Techniquement, WebFlux repose sur Project Reactor, une implémentation de la spécification Reactive Streams.

Au lieu de manipuler directement des valeurs ou des collections, on manipule des flux de données.

  • Mono représente la promesse d'un élément unique
Mono
  • Flux représente la promesse d'une collection d'éléments
Flux

Dans quels cas utiliser WebFlux ? 🤔

Spring WebFlux n'a pas vocation à remplacer Spring MVC dans tous les projets. Son véritable intérêt apparaît dans les contextes où les applications doivent gérer un grand nombre d'évènements, d'appels externes ou de connexions simultanées, sans compromettre la performance ni la stabilité.

⚡️ Quand les threads deviennent un goulet d'étranglement

Si une application doit interroger plusieurs services externes (APIs tierces, microservices internes...), un modèle bloquant gaspille beaucoup de ressources. Chaque appel qui attend une réponse mobilise un thread inutilement.

Avec WebFlux, de nombreux appels peuvent être lancés en parallèle, sans bloquer le traitement. Les threads sont alors libérés pendant l'attente, ce qui permet d'absorber un volume de requêtes bien plus élevé avec la même infrastructure.

C'est particulièrement utile pour des APIs d'agrégation de données.

🛜 Dans des architectures à forte latence IO

WebFlux excelle dans les environnements où la latence réseau est importante : bases de données distantes, APIs externes lentes, microservices avec une faible disponibilité... Dans ces situations, le non-bloquant devient un levier de résilience.

Pendant que certaines requêtes attendent des réponses, les threads peuvent continuer à traiter d'autres flux entrants.

De ce fait, l'application reste fluide, même lorsqu'elle sollicite des services externes lents.

📡 Pour le streaming et les flux de données en temps réel

WebFlux est naturellement adapté au streaming de données. Il supporte nativement Server-Sent Events (SSE) et les WebSockets, qui permettent d'envoyer des mises à jour continues au client.

C'est idéal pour tout système nécessitant un flux continu de données, comme un dashboard dynamique ou une application de messagerie instantanée.

Là où Spring MVC aurait besoin de maintenir des connexions coûteuses, WebFlux gère ces flux de manière asynchrone et scalable

🧩 Pour les pipelines d'évènements et le traitement asynchrone

Au-delà des APIs HTTP, WebFlux peut aussi servir de base à des applications évènementielles, comme de l'ingestion de logs, de consommation de messages Kafka ou RabbitMQ etc.

Le modèle réactif de Reactor permet de chaîner, transformer et filtrer les évènements comme un flux continu, sans avoir à bloquer le traitement.

Concrètement, ça ressemble à quoi ? ⚙️

Voici un exemple minimal de contrôleur avec WebFlux :

@RestController
@RequestMapping("/hello")
public class HelloController {

    @GetMapping
    public Mono<String> sayHello() {
        return Mono.just("Hello, reactive world!");
    }
}

Le code présenté ci-dessus illustre l'un des principaux changements : la méthode ne renvoie pas directement une chaîne de caractères, mais un Mono<String>.

Lorsqu'un client appelle cette API, Spring WebFlux s'occupe de publier la réponse dès qu'elle est émise par le Mono.

Pendant ce temps, le thread initial est libéré pour traiter d'autres requêtes.

Dans un contrôleur Spring MVC classique, on aurait ceci :

@RestController
@RequestMapping("/hello")
public class HelloController {

    @GetMapping
    public String sayHello() {
        return "Hello world!";
    }
}

Dans ce cas, le thread est monopolisé de l'appel du client à la réponse du serveur.

Conclusion

Spring WebFlux n'est pas un remplacement de Spring MVC, mais une évolution naturelle de la façon dont nous concevons les applications web modernes.

Il ne s'agit plus seulement de traiter des requêtes, mais de gérer des flux de données, de réagir à différents évènements, en maximisant l'efficacité de chaque ressource système.

Dans un monde où les applications doivent absorber des milliers de connexions simultanées ou diffuser des données en temps réel, WebFlux apporte une réponse élégante en proposant un modèle asynchrone, non-bloquant et réactif.

Ces caractéristiques répondent aux problématiques de performances, résilience et scalabilité.

Choisir WebFlux, c'est également raisonner en flux, qui s'enchaînent et se transforment. L'approche n'est plus séquentielle, mais déclarative.
On ne "fait" plus les choses pas à pas, on décrit comment elles doivent se produire, au rythme du flux de données. C'est une approche élégante et puissante, mais qui demande plus de réflexion et de recul pour bien maîtriser les interactions entre Mono et Flux

Ce premier article posait les bases et la philosophie de WebFlux.
Dans le prochain article de cette série, nous explorerons le fonctionnement interne de Mono et Flux, et verrons comment construire des chaînes réactives performantes, sans tomber dans les pièges du code asynchrone.

Il était une fois... Spring Boot
Salut, jeune explorateur du monde numérique ! Aujourd’hui, c’est moi, Spring Boot, qui viens te conter mon histoire, de mes débuts à aujourd’hui.

Dernier