I'm new to WebFlux. Developing file upload API. I want to save the uploaded file and meta to db and return the saved entity as a response. The lambda expression is not getting invoked in flatMap
on filePart.transferTo
. I feel using the block()
would make using WebFlux pointless. Any suggestions are appreciated.
public Mono<Music> uploadMusic(FilePart filePart) throws IOException {
File file = File.createTempFile("tmp-", filePart.filename());
file.deleteOnExit();
Music music = new Music();
return filePart.transferTo(file).flatMap((it) -> {
music.setFilePath(file.getAbsolutePath());
music.setMeta(new Metadata());
log.info(String.valueOf(music));
return this.musicRepository.save(music);
});
}
When I did snippet test I found that Mono<Void>
.flatMap returning Mono<SomeObj>
is seems to be the problem.
// Lambda expression not invoked
public Mono<Music> voidToObj(FilePart filePart) throws IOException {
Music music = new Music();
return Mono.just(music).then().flatMap(it -> {
music.setMeta(new Metadata());
log.info(music.toString());
return Mono.just(music);
});
}
// Lambda expression invoked
public Mono<Music> objToObj(FilePart filePart) throws IOException {
Music music = new Music();
return Mono.just(music).flatMap(it -> {
music.setMeta(new Metadata());
log.info(music.toString());
return Mono.just(music);
});
}
Mono<Void>
doesn't produce a value because Void is not an object. Basically it's the same as an empty Mono, it just completes without any actual element.
As per docs https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html
Mono<Void> should be used for Publisher that just completes without any value.
So a flatMap
, as well as any other method that is supposed to process a value, would never be called after Mono.just(music).then().flatMap
.
But if you just want to update and return the value you already have then you can do:
return filePart.transferTo(file).then(Mono.defer(() -> {
music.setFilePath(file.getAbsolutePath());
music.setMeta(new Metadata());
log.info(String.valueOf(music));
// assuming .save returns a publisher
return this.musicRepository.save(music);
});