I need to get information about a Book, Author and Publisher.
The Book contains information about the Author and Publisher.
I'm getting the BookInfo using the following method:
bookService.getBook( tenantId, bookId )
.zipWhen( book -> authorService.getAuthor( tenantId, book.getAuthorId() ) )
.zipWhen( tuple -> publisherService.getPublisher( tenantId, tupple.getT1().getPublisherId() ) )
.map( tuple -> new BookInfo( tupple.getT1().getT1(), tupple.getT1().getT2(), tupple.getT2() ) );
I'm using zipWhen to share the Book to the other method calls but as you can see it's a mess since at the end I get a tuple with another tuple inside.
Is there a better way of doing this?
Would even be possible to call the authorService and the publisherService in parallel?
CodePudding user response:
You can use the zip static operator which may take more than one source publisher (it would be the Author and Publisher) and combine the results in a Tuple2 then map the result in-place to a BookInfo object.
bookService.getBook(tenantId, bookId)
.flatMap(book -> Mono.zip(authorService.getAuthor(tenantId, book.getAuthorId()), publisherService.getPublisher(tenantId, book.getPublisherId()))
.map(tuple -> new BookInfo(book, tuple.getT1(), tupple.getT2()))
);
You may optionally make both authService and publisherServie subscribeOn a different scheduler to have results computed in parallel:
CodePudding user response:
You can use Mono.zip inside flatMap()
getBook(tenantId, bookId).flatMap(book ->
Mono.zip(
Mono.just(book),
getAuthor(tenantId, book.getAuthorId()),
getPublisher(tenantId, book.getPublisherId())
)
).map(tuple -> {
tuple.getT1(); // book
tuple.getT2(); // author
tuple.getT3(); // publisher
// ... build BookInfo here and return
})
flatMap() operator is async by it's nature
