DEV Community

loading...
Cover image for A Short Example of Real-Time Event Streaming Using Spring WebFlux

A Short Example of Real-Time Event Streaming Using Spring WebFlux

dariocarrasquel profile image Darío Carrasquel ・2 min read

Spring WebFlux is a framework for Java that provides support for reactive programming. This framework was created by PIVOTAL, the company behind the development of Spring, and it is based on the Reactor project.

Reactive programming is a paradigm that consists of seeing almost everything as a flow of elements (Stream). Currently, web applications require a lot of dynamism, which means that these applications execute operations in real-time.

Those who have dealt with AJAX in the past, surely remember when the time of the computer was periodically updated. This gave the appearance that everything happened online, it was not necessary to reload the whole page.

Reactive programming follows the Publisher/Subscriber scheme, similar to the Observer design pattern. Consequently, the client doesn't need to make so many requests to the server.

Example

We're going to start by doing a simple but very clear example to show the most basic features of Spring WebFlux. For this, we will use Spring Boot 2 which uses Spring Framework 5.

We can create a starting project in https://start.spring.io

Creation of a RestController

The first thing we're going to do is create a Controller with the @RestController annotation. This Controller will generate random integer numbers every second and then will return them using the Flux object.

The Mono and the Flux objects are the main building blocks of Spring WebFlux. If a particular operation returns a single entity, then the system returns a Mono object. If the operation returns multiple elements, a Flux type represents these elements.

@RestController
public class EventController {

    Logger logger = LoggerFactory.getLogger(EventController.class);

    @GetMapping(value = "/events", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<Integer> getNumbers() {
        Random r = new Random();
        int min = 0;
        int max = 32767;
        return Flux.fromStream(Stream.generate(() -> r.nextInt(max - min) + min)
            .map(s -> String.valueOf(s))
            .peek((msg) -> {
                logger.info(msg);
            }))
            .map(s -> Integer.valueOf(s))
            .delayElements(Duration.ofSeconds(1));
    }
}
Enter fullscreen mode Exit fullscreen mode

Note that the getNumbers() method produces a TEXT_EVENT_STREAM_VALUE. This indicates that the system sends data as Server Sent Events or SSE.

Creation of the Reactive EventClient

For the next step, we're going to create a Reactive EventClient:

public class EventClient {

    Logger logger = LoggerFactory.getLogger(EventClient.class);

    @Bean
    WebClient getWebClient() {
        return WebClient.create("http://localhost:8081");
    }

    @Bean
    CommandLineRunner demo(WebClient client) {
        return args -> {
            client.get()
                .uri("/events")
                .accept(MediaType.TEXT_EVENT_STREAM)
                .retrieve()
                .bodyToFlux(Integer.class)
                .map(s -> String.valueOf(s))
                .subscribe(msg -> {
                    logger.info(msg);
                });
        };
    }
}
Enter fullscreen mode Exit fullscreen mode

As we're expecting a flux of events we need to use the bodyToFlux() method in order to return a proper response.

Now we run the Spring Boot application. Every second, the system will generate and print random numbers on the console.

Conclusion

With this simple example, we can observe the most basic features of real-time event streaming using Spring WebFlux.

In conclusion, reactive programming consists of seeing everything as a flow of elements, hence, it allows the execution of operations on that flow and being able to transmit it to a client in such a way that it has an asynchronous experience and Spring WebFlux is a great option to consider if our tasks require these capabilities.

Discussion (0)

pic
Editor guide