Lets suppose these two scenarios of a controller that generates some random numbers with a delay:
1) Reactive Spring 5 reactive application:
@GetMapping("/randomNumbers")
public Flux<Double> getReactiveRandomNumbers() {
return generateRandomNumbers(10, 500);
}
/**
* Non-blocking randon number generator
* @param amount - # of numbers to generate
* @param delay - delay between each number generation in milliseconds
* @return
*/
public Flux<Double> generateRandomNumbers(int amount, int delay){
return Flux.range(1, amount)
.delayMillis(delay)
.map(i -> Math.random());
}
2) Traditional Spring MVC with DeferredResult
:
@GetMapping("/randomNumbers")
public DeferredResult<Double[]> getReactiveRandomNumbers() {
DeferredResult<Double[]> dr = new DeferredResult<Double[]>();
CompletableFuture.supplyAsync(() -> {
return generateRandomNumbers(10, 500);
}).whenCompleteAsync((p1, p2) -> {
dr.setResult(p1);
});
return dr;
}
/**
* Blocking randon number generator
* @param amount - # of numbers to generate
* @param delay - delay between each number generation in milliseconds
* @return
*/
public Double[] generateRandomNumbers(int amount, int delay){
int generated = 0;
Double [] d = new Double[amount];
while(generated < amount){
try {
Thread.sleep(delay);
} catch (InterruptedException e) {}
d[generated] = Math.random();
generated++;
}
return d;
}
From the perspective of a HTTP client (browser, AJAX request) there isn't any difference between both scenarios. I mean the client will wait until all the results are sent, and won't process them until the whole response is committed.
That is to say, although spring web reactive makes us think that it's sending the results back as they are being produced, in reality it doesn't happen that way and the client won't be able to process the results until all the numbers have been generated.
The straightforward way to make the client fully reactive would be to use WebSockets.
So, apart from the cool stuff (such as nice semantics, composition...), what is the point of using Spring Web Reactive considering that browser HTTP requests aren't reactive and are equivalent to using the traditional DeferredResult?