Here's my code:
public Mono<Foo> doSomething(String fooId, String barId) {
Mono<Foo> firstResult = firstServiceCall(fooId, barId);
Mono<List<Baz>> secondResult = secondServiceCall(fooId);
return firstResult.flatMap(secondResult::thenReturn);
}
private Mono<Foo> firstServiceCall(String fooId, String barId) {
return fooRepo
.findByFooIdAndBarId(fooId, barId)
.switchIfEmpty(Mono.error(new ResponseStatusException(NOT_FOUND)))
.filter(Foo::isSomething)
.switchIfEmpty(Mono.error(new ResponseStatusException(UNPROCESSABLE_ENTITY)))
.doOnNext(foo -> foo.setSomething(false))
.flatMap(fooRepo::save);
}
private Mono<List<Baz>> secondServiceCall(String fooId) {
var filter = new BazSearchFilter();
filter.setFooId(fooId);
return bazRepo
.findAllByFilter(filter)
.doOnNext(baz -> baz.setStatus(BazStatus.SOMETHING))
.collectList()
.flatMapMany(bazRepo::saveAll)
.collectList();
}
For some reason, the doSomethingMethod always calls the secondServiceCall method despite an error signal being propagated from the firstServiceCall method (the NOT_FOUND or UNPROCESSABLE_ENTITY scenarios).
I would expect the secondServiceCall not to go off since I'm using flatMap, but maybe I'm missing something.
Does anyone know how to fix this?
> secondResult` is eagerly evaluated because it depends on the `String fooId` parameter of the `doSomething` method and does not depends on the result of the `firstServiceCall(...)` so the second service gets called even before a flatMap transformation occurs. See also [what does Mono.defer() do?](https://stackoverflow.com/a/55972232/13794675)
– Alex Shavlovsky Jun 24 '20 at 22:47