I'm working with Spring Webflux + R2DBC to insert some data into a database.
Call for data -> Put in database -> Return data.
Controller
@RestController
public class UtilController {
private final FooService service;
@Autowired
public UtilController(FooService service) { this.service = service; }
@GetMapping(path = "/load-data")
public Mono<List<Foo>> loadFoos() { return service.addFoos(); }
}
Service
public Mono<List<Foo>> addFoos() {
return webClient.getSomeStuff()
.map(results -> results.stream()
.map(/* ...transform to domain model */)
.toList())
.map(foos -> {
// This is the problem site.
List<Foo> buf = new ArrayList<>();
foos.forEach(f -> {
fooDao.createFoo(l)
.doOnNext(buf::add)
.next()
.subscribe();
});
return buf;
});
}
DAO
public Flux<Foo> createFoo(final Foo foo) {
var query = "<INSERT_STUFF_STATEMENT>";
// "publisher" is private final Publisher<? extends Connection> publisher;
var connection = Mono.from(publisher);
return connection.flatMapMany(c -> c.createStatement(query)
.bind("STUFF", foo.getStuff())
.execute())
.map(result -> Foo.builder()
.stuff(whatever)
.build());
}
The main problem is I can't figure out how to make it wait for all the results to be returned and added to the eventual List<Foo>
to return back to the controller. There must be some combo of the map
/flatMap
/flatMapMany
/etc...
that I'm missing to do this correctly. As it stands, it only gets about 80% of the data into the db and 10% into the array before the controller sends back the response and shuts down the processing