Small question about the webflux reactive repository, especially about the methods saveAll Flux saveAll(Iterable var1); versus Flux saveAll(Publisher var1);
Wanted to compare, I wrote the following:
@Controller @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class); } @Autowired private SomeReactiveRepository someReactiveRepository; @PostMapping(path = "/saveListInsideMono", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public Mono<QuestionResponse> saveListInsideMono(@RequestBody Mono<QuestionRequest> questionRequestMono) { //just doing some business transformation on the list inside the mono Mono<List<String>> enhancedStringListMono = questionRequestMono.map(questionRequest -> enhance(questionRequest)); //take the pojo inside the mono and map it to a saveAllAndConvertToResponse method (see next method) Mono<QuestionResponse> questionResponseMono = enhancedStringListMono.map(enhancedStringList -> saveAllAndConvertToResponse(enhancedStringList)); return questionResponseMono; } private QuestionResponse saveAllAndConvertToResponse(List<String> enhancedStringList) { // use the repository <S extends T> Flux<S> saveAll(Iterable<S> var1); + subscribe return someReactiveRepository.saveAll(enhancedStringList).thenReturn(new QuestionResponse(enhancedStringList)); //this also works but not good to subscribe //someReactiveRepository.saveAll(enhancedStringList).subscribe(); //return new QuestionResponse(enhancedStringList); } @PostMapping(path = "/saveFlux", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public Mono<QuestionResponse> saveFlux(@RequestBody Mono<QuestionRequest> questionRequestMono) { //just doing some business transformation on the list inside the mono Mono<List<String>> enhancedStringListMono = questionRequestMono.map(questionRequest -> enhance(questionRequest)); // use the repository <S extends T> Flux<S> saveAll(Publisher<S> var1); to save the flatMapMany + fromIterable directly Flux<String> enhancedStringFlux = someReactiveRepository.saveAll(enhancedStringListMono.flatMapMany(Flux::fromIterable)); Mono<QuestionResponse> questionResponseMono = enhancedStringFlux.collectList().map(enhancedString -> convertToResponse(enhancedString)); return questionResponseMono; } private QuestionResponse convertToResponse(List<String> enhancedStringList) { //return the object needed return new QuestionResponse(enhancedStringList); } private static List<String> enhance(QuestionRequest questionRequest) { //dummy business transformation logic List<String> baseList = questionRequest.getList(); List<String> enhancedList = baseList.stream().map(oneString -> "enhanced" + oneString).collect(Collectors.toList()); return enhancedList; } public class QuestionRequest { private List<String> list; public List<String> getList() { return list; } } public class QuestionResponse { private List<String> enhancedList; public QuestionResponse(List<String> enhancedList) { this.enhancedList = enhancedList; } } }
In terms of “correctness” both codes are doing what is expected. Everything is persisted successfully.
But in terms of performance, reactive paradigm, IO Utilisations to DB, Netty Core usage, what is the “best” solution and why please?
Thank you
Advertisement
Answer
It all depends on what objects you currently have. If you have a Flux
of objects, use the saveAll method that takes a Publisher
. If you have the actual Collection
of objects, use the saveAll method that takes an Iterable
.
As an example, if you look at the implementation SimpleReactiveCassandraRepository
the implementation of saveAll that takes an Iterable
just wraps it in a Flux and delegates to the saveAll method that accepts a Flux
public <S extends T> Flux<S> saveAll(Iterable<S> entities) { Assert.notNull(entities, "The given Iterable of entities must not be null"); return saveAll(Flux.fromIterable(entities)); }
As a result, there should no difference in terms of IO utilisation or netty core usage. Also, both follow the reactive paradigm.