2
votes

I'm trying to make sense of reactive endpoints in Spring, and this is confusing me.

// in a @RestController
@GetMapping("/someendpoint")
fun someEndpoint(): ResponseEntity<Mono<Map<String, Any>>> {
    return ResponseEntity(Mono.zip(
        Mono.fromRunnable<List<SomeItem>> { someApiCall() },
        Mono.fromRunnable<List<SomeOtherItem>> { someOtherApiCall() },
    ).map { tuple ->
        val someItems = tuple.t1
        val someOtherItems = tuple.t2
        mapOf(
            "someItems" to someItems,
            "someOtherItems" to someOtherItems
        )
    }, HttpStatus.OK)
}

I have an endpoint that returns a Mono of a Map, the idea being just to render some arbitrary JSON.

As part of the request, I do a Mono.zip(Mono.fromRunnable { ... }) where I call API's for data.

After the zip, I do a .map over the results and ultimately return the Map that I expect to see rendered.

When I hit the endpoint, no JSON is rendered, but the runnables in the zip are called and the response time takes those API calls into account. The .map after the .zip is never called. I'm probably just not understanding something simple here--like the .map is not subscribed to?

What is going on here and what is the usual way to handle a situation like this using Webflux/Reactor?

1
Use Mono.fromSupplier() instead of fromRunnable. fromRunnable returns an empty Mono, see projectreactor.io/docs/core/release/api/reactor/core/publisher/…Rene
Thanks, that did the trick!CodeMonkeyCharlie

1 Answers

0
votes

As Rene mentioned in the comment, my mistake was using Mono.fromRunnable {} instead of Mono.fromSupplier {}