Episode ini membuka dunia reaktif: konsep Mono dan Flux beserta backpressure, membangun aplikasi non-blocking dengan Spring WebFlux, integrasi database reaktif dengan R2DBC, serta perbandingan reaktif vs servlet-based.

Model servlet tradisional memakai satu thread per request. Ketika ribuan request datang bersamaan, thread habis dan server kewalahan. Reactive programming menawarkan pendekatan berbeda: sedikit thread melayani banyak request secara non-blocking.
Episode 15 memperkenalkan Spring WebFlux dan Project Reactor. Kalian akan memahami Mono dan Flux, konsep backpressure, membangun endpoint non-blocking, dan menghubungkannya ke database reaktif R2DBC — lalu menilai kapan pendekatan ini tepat.
Project Reactor memperkenalkan dua tipe publisher:
Mono<String> mono = Mono.just("satu nilai");
Flux<Integer> flux = Flux.just(1, 2, 3, 4, 5);Data mengalir secara asynchronous: publisher memancarkan nilai, dan subscriber bereaksi saat nilai tiba. Tidak ada blocking thread — inilah inti paradigma reaktif.
Backpressure adalah mekanisme di mana subscriber memberi tahu publisher seberapa cepat ia bisa menerima data. Jika subscriber lambat, publisher menyesuaikan kecepatan atau membatasi jumlah elemen:
flux.subscribe(
nilai -> System.out.println("Menerima: " + nilai),
error -> error.printStackTrace(),
() -> System.out.println("Selesai")
);Reactor menerapkan backpressure lewat request n elemen dari subscriber. Ini mencegah pemroses lambat tenggelam oleh banjir data — masalah yang lazim di sistem streaming.
WebFlux disediakan oleh starter dengan server reaktif Netty:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>Starter ini menggantikan Tomcat dan spring-boot-starter-web — aplikasi berjalan di atas Netty dengan model event-loop non-blocking.
Controller WebFlux mengembalikan Mono dan Flux, bukan object biasa:
@RestController
@RequestMapping("/api/items")
public class ItemController {
private final ItemService service;
public ItemController(ItemService service) {
this.service = service;
}
@GetMapping
public Flux<Item> listItems() {
return service.findAll();
}
@GetMapping("/{id}")
public Mono<ResponseEntity<Item>> getItem(@PathVariable Long id) {
return service.findById(id)
.map(ResponseEntity::ok)
.defaultIfEmpty(ResponseEntity.notFound().build());
}
}Tidak ada thread yang menunggu. Saat data siap, respons dikirim; saat belum, thread dipakai untuk request lain. Perhatikan penggunaan defaultIfEmpty untuk menangani data yang tidak ditemukan.
Kekuatan Reactor ada di operator yang bisa dirangkai. Contoh menggabungkan dua sumber data:
Mono<Item> item = service.findById(1L);
Mono<Supplier> supplier = supplierService.findById(1L);
Mono<ItemDetail> detail = Mono.zip(item, supplier)
.map(tuple -> new ItemDetail(tuple.getT1(), tuple.getT2()));Mono.zip menggabungkan hasil dua publisher menjadi satu — keduanya dijalankan secara paralel tanpa memblokir thread. Rantai operator seperti map, flatMap, dan zip membangun pipeline data yang elegan. Dari sisi client, endpoint reaktif tetap diuji biasa: curl http://localhost:8080/api/items.
R2DBC memungkinkan akses database secara reaktif. Tambahkan dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-r2dbc</artifactId>
</dependency>
<dependency>
<groupId>io.r2dbc</groupId>
<artifactId>r2dbc-postgresql</artifactId>
</dependency>Konfigurasikan koneksi R2DBC:
spring:
r2dbc:
url: r2dbc:postgresql://localhost:5432/belajar
username: belajar
password: rahasiaRepository reaktif bekerja sama dengan Mono dan Flux:
public interface ItemRepository
extends ReactiveCrudRepository<Item, Long> {
Flux<Item> findByNameContaining(String keyword);
}Semua method — save, findAll, findById — mengembalikan publisher, sehingga tidak ada pemblokiran saat berkomunikasi dengan database. Seluruh pipeline dari request HTTP sampai query database menjadi non-blocking.
Perbandingan yang perlu kalian pahami:
Reaktif bukan pengganti universal. Logika blocking — seperti panggilan JDBC blocking — mematikan manfaat reaktif. WebFlux paling bersinar di aplikasi yang didominasi operasi I/O asynchronous dan membutuhkan skala koneksi besar.
Traffic tinggi, I/O intensif -> WebFlux
Aplikasi bisnis standar -> Spring MVCEpisode 15 membekali kalian dengan pemrograman reaktif: memahami Mono, Flux, dan backpressure, membangun aplikasi non-blocking dengan Spring WebFlux, mengintegrasikan database reaktif R2DBC, serta menilai kapan paradigma reaktif lebih unggul dari servlet-based.
Inti yang harus dibawa pulang:
Mono memancarkan satu nilai; Flux memancarkan banyak nilai secara stream.Mono dan Flux, bukan object biasa.Di episode 16 selanjutnya kita akan membahas performance dan JVM optimizations — profiling dengan JFR dan async-profiler, tuning heap dan JVM flags dengan GC G1 dan ZGC, optimasi startup time dan memory footprint, serta tuning cache dan connection pool.