I am using Spring Webflux, and I need to return the object of Author from Mono<Book>
, But I don’t know how to do it more correctly.
The method that should return Author
:
private Author getRegistredAuthor(Book bookInput) {
String fullName = bookInput.getAuthor().getFullName();
Optional<Author> optionalAuthor = repository.findByFullName(fullName).blockOptional();
if(optionalAuthor.isPresent()){
return optionalAuthor.get();
}else {
Author author = Author.builder().fullName(fullName).build();
return repository.insert(author).block();
}
}
The method that uses Author
to create a new entity:
public Mono<BookDto> create(@RequestBody Book book) {
book.setAuthor(getRegistredAuthor(book));
return bookRepository.insert(book)
.map(BookDto::of);
}
As I understand it, if I use block()
, I will greatly reduce the effectiveness of reactive.
Will it be more effective if I use so ?
return repository.insert(author).blockOptional().get();
How would it be most efficient to return an object of Author
?
As a result, I solved my problem using Mono.zip. Maybe my solution will help someone too:
@PostMapping("/api/book")
public Mono<BookDto> create(@RequestBody Book book) {
return getObjectMono(book).flatMap(b -> bookRepository.insert(book))
.map(BookDto::of);
}
private Mono<Object> getObjectMono(Book book) {
return Mono.zip(
getRegistredAuthor(book),
getRegistredGenre(book)
).map(objects -> {
book.setAuthor(objects.getT1());
book.setGenre(objects.getT2());
return book;
});
}
private Mono<Genre> getRegistredGenre(Book bookInput) {
String genreTitle = bookInput.getGenre().getTitle();
return genreRepository.findByTitle(genreTitle)
.switchIfEmpty(
genreRepository.insert(Genre.builder().title(genreTitle).build())
);
}
private Mono<Author> getRegistredAuthor(Book bookInput) {
String fullName = bookInput.getAuthor().getFullName();
return authorRepository.findByFullName(fullName)
.switchIfEmpty(
authorRepository.insert(Author.builder().fullName(fullName).build())
);
}