`flatMap()` transforms an item by passing it to a function that returns a `Mono` or `Flux`. It then flattens that publisher’s results into the resulting reactive sequence. Use it when the transformation itself produces a publisher, such as a reactive repository save. section 11.3.3 section 12.1.2
The difference from `map()` matters: `map()` transforms each item directly and synchronously. If a mapping function returns a `Mono<TacoOrder>`, using `map()` on a `Mono` would leave a `Mono<Mono<TacoOrder>>`. Using `flatMap()` leaves a `Mono<TacoOrder>` that the next operation can use. section 11.3.3 section 13.1.4
@Test
public void flatMap() {
Flux<Player> playerFlux = Flux
.just("Michael Jordan", "Scottie Pippen", "Steve Kerr")
.flatMap(n -> Mono.just(n)
.map(p -> {
String[] split = p.split("\\s");
return new Player(split[0], split[1]);
})
.subscribeOn(Schedulers.parallel())
);
List<Player> playerList = Arrays.asList(
new Player("Michael", "Jordan"),
new Player("Scottie", "Pippen"),
new Player("Steve", "Kerr"));
StepVerifier.create(playerFlux)
.expectNextMatches(p -> playerList.contains(p))
.expectNextMatches(p -> playerList.contains(p))
.expectNextMatches(p -> playerList.contains(p))
.verifyComplete();
}
Follow each player name into its own `Mono`: `map()` creates the `Player`, `subscribeOn(Schedulers.parallel())` schedules the subscription, and `flatMap()` combines the results. The test checks membership rather than a fixed emission order. section 11.3.3
`flatMap()` does not itself schedule work on another thread. Paired with `subscribeOn()`, it allows the publishers created for individual items to perform transformations asynchronously. The same pattern can process buffered groups of fruit on parallel workers. section 11.3.3
Save a taco from a reactive request body
A WebFlux controller can accept `Mono<Taco>` and return `tacoMono.flatMap(tacoRepo::save)`. When the taco arrives, the repository’s reactive `save()` supplies a new `Mono<Taco>`; `flatMap()` keeps the controller’s result a `Mono<Taco>`. section 12.1.2
Continue after a WebClient response
A WebClient response flow can return `Mono.empty()` when an `X_UNAVAILABLE` header is true, or continue with the response. A following `flatMap(cr -> cr.bodyToMono(Ingredient.class))` extracts the ingredient while keeping the result a `Mono<Ingredient>`. section 12.4.5
Repository workflows use the same idea across several steps. Saving an order first saves its tacos, adds their assigned IDs to the order, and continues with a `Mono<TacoOrder>` rather than nesting publishers. Reading an order can likewise use `flatMap()` to fetch and attach its tacos. section 13.1.4




