Flavouski
Flavouski

Reputation: 141

Concat multiple reactive requests to one Mono

I noticed in the reactive libraries there are Tuples, but what do I do if there are more than 8 Tuples?

https://projectreactor.io/docs/core/release/api/reactor/util/function/Tuples.html#fromArray-java.lang.Object:A-

Example code that seems to work, but is there a better way to use some sort of collector?

private Mono<List<String>> getContent(List<String> ids) {
    List<String> allContent = new ArrayList<>();
    Mono<List<String>> allContentMono = Mono.empty();
    for(String id : ids) {
        allContentMono = callApi(id)
        .flatMap(result -> result.bodyToMono(String.class))
        .map(str -> {
            allContent.add(str); 
            return allContent;
        });
    }
    return allContentMono;
}

Why did the tuple size stop at 8? (haven't looked around for the documentation on why, but not my main concern)

Thanks

Upvotes: 1

Views: 4798

Answers (1)

Simon Basl&#233;
Simon Basl&#233;

Reputation: 28301

zip (which uses TupleN) is for when you want to create values by compositon, out of a combination of sources. Eg. out of a Flux<FirstName> and Flux<LastName> you want a Flux<FullName>, that emits one FullName for each incoming FistName/LastName pair.

For your use case, where you want to execute multiple calls (possibly in parallel) and collect the results in a list, flatMap is enough:

private Mono<List<String>> getContent(List<String> ids) {
    return Flux
        .fromIterable(ids)
        .flatMap(id -> callApi(id))
        .flatMap(response -> response.bodyToMono(String.class))
        .collectList();
}

Tuple is an immutable, fixed-size data structure, used by zip as convenience when you don't want to create a dedicated POJO. It doesn't make sense to try and support unlimited sizes so we stopped at eight. There is a zip variant that will aggregate more than 8 sources, but will make you work with an Object[] instead of a Tuple.

Upvotes: 1

Related Questions