Over a million developers have joined DZone.

Spring-Reactive Example REST Application

Spring Reactive is a sandbox for experimenting on the reactive support intended to be part of Spring Framework 5. This post provides an example REST application built with this library.

· Integration Zone

Build APIs from SQL and NoSQL or Salesforce data sources in seconds. Read the Creating REST APIs white paper, brought to you in partnership with CA Technologies.

Spring-Reactive aims to bring reactive programming support to Spring-based projects and is expected to be available for the timelines of Spring 5. My intention here is to exercise some of the very basic signatures for REST endpoints with this model.

Before I go ahead, let me acknowledge that this entire sample is completely based on the samples which Sébastien Deleuze has put together here - https://github.com/sdeleuze/spring-reactive-playground.

I wanted to consider three examples: first a case where existing Java 8 CompletableFuture is returned as a type; second where RxJava's Observable is returned as a type; and third with Spring Reactor Core'sFlux type.

Expected Protocol

The structure of the request and response message handled by each of the three services is along these lines, all of them will take in a request which looks like this:

    "delay_by": 2000,
    "payload": "Hello",
    "throw_exception": false

The delay_by will make the response delayed and throw_exception will make the response error out. A sane response would be the following:

    "id": "1",
    "received": "Hello",
    "payload": "Response Message"

I will be ignoring the exceptions for this post.

CompletableFuture as a Return Type

Consider a service which returns a Java 8 CompletableFuture as a return type:

public CompletableFuture<MessageAcknowledgement> handleMessage(Message message) {
    return CompletableFuture.supplyAsync(() -> {
        return new MessageAcknowledgement(message.getId(), message.getPayload(), "data from CompletableFutureService");
    }, futureExecutor);

The method signature of a Controller which calls this service looks like this now:

public class CompletableFutureController {

    private final CompletableFutureService aService;

    public CompletableFutureController(CompletableFutureService aService) {
        this.aService = aService;

    @RequestMapping(path = "/handleMessageFuture", method = RequestMethod.POST)
    public CompletableFuture<MessageAcknowledgement> handleMessage(@RequestBody Message message) {
        return this.aService.handleMessage(message);

When the CompletableFuture completes the framework will ensure that the response is marshaled back appropriately.

Rx Java Observable As a Return Type

Consider a service which returns a Rx Java Observable as a return type:

public Observable<MessageAcknowledgement> handleMessage(Message message) {
    logger.info("About to Acknowledge");
    return Observable.just(message)
        .delay(message.getDelayBy(), TimeUnit.MILLISECONDS)
        .flatMap(msg -> {
        if (msg.isThrowException()) {
            return Observable.error(new IllegalStateException("Throwing a deliberate exception!"));
        return Observable.just(new MessageAcknowledgement(message.getId(), message.getPayload(), "From RxJavaService"));

The controller invoking such a service can directly return the Observable as a type now and the framework will ensure that once all the items have been emitted the response is marshaled correctly.

public class RxJavaController {

    private final RxJavaService aService;

    public RxJavaController(RxJavaService aService) {
        this.aService = aService;

    @RequestMapping(path = "/handleMessageRxJava", method = RequestMethod.POST)
    public Observable<MessageAcknowledgement> handleMessage(@RequestBody Message message) {
        System.out.println("Got Message..");
        return this.aService.handleMessage(message);

Note that since Observable represents a stream of 0 to many items, this time around the response is a JSON array.

Spring Reactor Core Flux As a Return Type

Finally, if the response type is a Flux type, the framework ensures that the response is handled cleanly. The service is along these lines:

public Flux

    handleMessage(Message message) {
        return Flux.just(message)
            .map(msg -> Tuple.of(msg, msg.isThrowException()))
            .flatMap(tup -> {
        if (tup.getT2()) {
            return Flux.error(new IllegalStateException("Throwing a deliberate Exception!"));
        Message msg = tup.getT1();
        return Flux.just(new MessageAcknowledgement(msg.getId(), msg.getPayload(), "Response from ReactorService"));

and a controller making use of such a service:

public class ReactorController {

    private final ReactorService aService;

    public ReactorController(ReactorService aService) {
        this.aService = aService;

    @RequestMapping(path = "/handleMessageReactor", method = RequestMethod.POST)
    public Flux<MessageAcknowledgement> handleMessage(@RequestBody Message message) {
        return this.aService.handleMessage(message);


This is just a sampling of the kind of return types that the Spring Reactive project supports, the possible return types is way more than this - here is a far more comprehensive example.

I look forward to when the reactive programming model becomes available in the core Spring framework.

The samples presented in this blog post is available at my GitHub repository

The Integration Zone is brought to you in partnership with CA Technologies.  Use CA Live API Creator to quickly create complete application backends, with secure APIs and robust application logic, in an easy to use interface.

flux ,spring ,rest ,reactive

Published at DZone with permission of Biju Kunjummen, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}