Kotlin Coroutines & Reactive
The big one: suspend + WebFlux, coroutine↔Reactor bridging (awaitBody/awaitSingle/mono{}), Flow↔Reactor, structured concurrency, dispatchers, timeouts & retries.
- Step 1
The suspend + WebFlux mental model
In WebFlux, suspend doesn't make your handler faster — it lets one thread serve thousands of requests by parking work instead of blocking.
Read lesson - Step 2
Bridging Coroutines and Reactor
Speak both dialects fluently: await a Mono/Flux from suspend code, and wrap suspend code back into a Publisher.
Read lesson - Step 3
Flow ↔ Reactor: Bridging Coroutines and WebFlux
One conversion call turns a Reactor Flux into an idiomatic Kotlin Flow — and back into a streaming WebFlux response.
Read lesson - Step 4
Structured Concurrency in Suspend Handlers
Fan out parallel calls with coroutineScope, survive partial failures with supervisorScope, and let client disconnects cancel everything for free.
Read lesson - Step 5
Coroutine Context & Dispatchers: withContext(Dispatchers.IO)
Suspend functions are a promise not to block — keep that promise by parking blocking calls on Dispatchers.IO.
Read lesson - Step 6
Resilience: Timeouts and Retries with Coroutines and Reactor
A slow dependency is a failing dependency — bound every suspend call with a timeout, then retry it with backoff.
Read lesson - Step 7
Error Handling Across the Bridge: Exceptions, onError, and Fallbacks
A thrown exception and a Reactor onError signal are two faces of the same failure — the bridge translates between them so you can catch what you expect where you expect it.
Read lesson - Step 8
Testing the Reactive Stack: runTest, StepVerifier, and WebTestClient
Asynchronous code deserves synchronous, deterministic tests — and the JVM ecosystem gives you one precise tool for every layer.
Read lesson