2

So right now, I am returning a response looking like

    @GetMapping("/integers")
    @ResponseStatus(code = HttpStatus.OK)
    public Mono<Map<String, Flux<Integer>>> getIntegers() {
        Mono<Map<String, Flux<Integer>>> integers = 
               Mono.just(Map.of("Integers", integerService.getIntegers()));
        return integers;
    }

which gives me a response of

{"Integers":{"scanAvailable":true,"prefetch":-1}}

where I expected it to stream the Flux<Integer> part as well, but it didn't. How would I do this in Spring webflux?

1 Answer 1

6

Spring WebFlux can only deal with one reactive type and won't deal with nested reactive types (like a Mono<Flux<Integer>>). Your controller method can return a Mono<Something>, a Flux<Something>, a ResponseEntity<Mono<Something>>, a Mono<ResponseEntity<Something>>, etc - but never nested reactive types.

The strange data you're seeing in the response is Jackson actually trying to serialize a reactive type (so you're looking at the promise for the data, not the data itself).

In this case, you could rewrite your method like this:

@GetMapping("/integers")
@ResponseStatus(code = HttpStatus.OK)
public Mono<Map<String, Flux<Integer>>> getIntegers() {
    Flux<Integer> integers = integerService.getIntegers();
    Mono<Map<String, List<Integer>>> result = integers
            // this will buffer and collect all integers in a Mono<List<Integer>>
            .collectList()
            // we can then map that and wrap it into a Map
            .map(list -> Collections.singletonMap("Integers", list));
    return result;
}

You can read more about the supported return values in the Spring WebFlux reference documentation.

Sign up to request clarification or add additional context in comments.

4 Comments

I see, well I ended up chainging the @Getmapping to produce MediaType.APPLICATION_STREAM_JSON_VALUE because I was not sure, if returning a pure Flux<Integer> would stream the data to the client and not do any sort of buffering. Largely, due to the fact that i am returning a billion heavy objects(integer was just a placeholder for the actual business object) In your case, could the integers.collectToList() throw a Out of Heap Memory exception if the Flux<Integer> integers has a lot of things it's going to stream
sorry, edited the comment above. I pressed enter accidentally, before writing everything
Haha, I'm often hitting that problem with SO comments. You're right. In this case, streaming values is the right choice - Flux.collectList does buffer everything in memory, so this is not the best choice for large collections/objects.
Hehe, well I've noticed you around a lot of spring webflux related questions on SO, so your hands must be keystroke-happy by now That makes sense, thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.