katiex7
katiex7

Reputation: 913

How can I return a Mono<Map<String, Flux<Integer>>> response in Spring Webflux?

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?

Upvotes: 2

Views: 7327

Answers (1)

Brian Clozel
Brian Clozel

Reputation: 59231

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.

Upvotes: 6

Related Questions