Belajar Quarkus - Reactive Programming & Vert.x
Episode 15 of 24

Belajar Quarkus - Reactive Programming & Vert.x

Episode ini membahas reactive programming di Quarkus: reactive stack dengan Vert.x, konsep Uni dan Multi untuk pemrosesan asynchronous, reactive messaging dengan Kafka, AMQP, atau MQTT, serta kapan menggunakan reactive dibandingkan imperative.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

Aplikasi modern harus melayani ribuan request bersamaan. Model blocking tradisional menahan satu thread untuk satu request — boros dan tidak scalable. Reactive programming menawarkan alternatif: satu thread melayani banyak operasi secara non-blocking.

Episode 15 membahas reactive stack Quarkus yang dibangun di atas Vert.x, konsep Uni dan Multi untuk pemrosesan asynchronous, reactive messaging dengan Kafka, AMQP, atau MQTT, serta panduan kapan memakai reactive dibandingkan imperative.

Reactive Stack dengan Vert.x di Quarkus

Vert.x di Inti Quarkus

Vert.x adalah toolkit event-driven yang menjadi fondasi non-blocking Quarkus. RESTEasy Reactive, reactive routes, dan event loop semuanya berjalan di atas Vert.x. Model utamanya: event loop yang memproses event secara non-blocking dan worker thread untuk pekerjaan blocking.

Setiap aplikasi Quarkus secara default memiliki beberapa event loop. Permintaan REST diproses di event loop; pekerjaan blocking (seperti JDBC sinkron) dilimpahkan ke worker.

Reactive Routes

Selain JAX-RS, Quarkus menawarkan reactive routes berbasis Vert.x: annotate method dengan @Route(path = "/api/status", methods = HttpMethod.GET) dan terima RoutingContext untuk menulis response langsung. Untuk API JSON sederhana, RESTEasy Reactive (episode 5) lebih nyaman; reactive routes berguna untuk kontrol tingkat rendah.

Uni dan Multi: Konsep Asynchronous

Uni untuk Satu Hasil

Uni mewakili satu hasil (atau satu kegagalan) di masa depan. Ini padanan reaktif dari CompletableFuture:

JavaUni untuk satu hasil
import io.smallrye.mutiny.Uni;
import jakarta.enterprise.context.ApplicationScoped;
 
@ApplicationScoped
public class QuoteService {
 
    public Uni<String> ambilQuote() {
        return Uni.createFrom().item("Halo, dunia reactive!")
            .onItem().delayIt().by(java.time.Duration.ofMillis(100));
    }
}

Uni.createFrom().item("...") membuat Uni langsung sukses. Rangkaian .onItem() dan .delayIt() membangun pipeline transformasi tanpa memblokir thread.

Multi untuk Aliran Data

Multi mewakili aliran (stream) beberapa item. Cocok untuk data streaming atau event:

JavaMulti menghasilkan aliran data
import io.smallrye.mutiny.Multi;
import java.time.Duration;
 
public Multi<Integer> hitung() {
    return Multi.createFrom()
        .range(1, 10)
        .onItem().transform(n -> n * n);
}

Multi.createFrom().range(1, 10) memancarkan 1 sampai 9, lalu .transform(n -> n * n) mengubah tiap item menjadi kuadratnya. Konsumen bisa subscribe untuk menerima item satu per satu.

Memakai Uni di Endpoint

RESTEasy Reactive mendukung tipe Mutiny secara langsung:

JavaEndpoint reactive
import io.smallrye.mutiny.Uni;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
 
@Path("/api/quote")
public class QuoteResource {
 
    @Inject
    QuoteService quoteService;
 
    @GET
    public Uni<String> quote() {
        return quoteService.ambilQuote();
    }
}

Method mengembalikan Uni<String> — request tidak memblokir thread; hasil dikirim saat Uni selesai. Ini model inti reactive REST.

Reactive Messaging dengan Kafka, AMQP, atau MQTT

Reactive Messaging

SmallRye Reactive Messaging menghubungkan aplikasi dengan broker pesan secara asynchronous. Tambahkan extension:

Tambahkan extension Kafka
./mvnw quarkus:add-extension -Dextensions=reactive-messaging-kafka

Producing dan Consuming

JavaProducer dan consumer pesan
import jakarta.enterprise.context.ApplicationScoped;
import org.eclipse.microprofile.reactive.messaging.Channel;
import org.eclipse.microprofile.reactive.messaging.Emitter;
import org.eclipse.microprofile.reactive.messaging.Incoming;
import io.smallrye.mutiny.Uni;
 
@ApplicationScoped
public class OrderMessaging {
 
    @Channel("orders-out")
    Emitter<String> ordersEmitter;
 
    public void kirimOrder(String order) {
        ordersEmitter.send(order);
    }
 
    @Incoming("orders-in")
    public void prosesOrder(String order) {
        System.out.println("Order diterima: " + order);
    }
}

@Channel("orders-out") mengirim ke channel Kafka, @Incoming("orders-in") menerima dari channel lain. Konfigurasi connector:

Konfigurasi channel Kafka
mp.messaging.outgoing.orders-out.connector=smallrye-kafka
mp.messaging.outgoing.orders-out.topic=orders
mp.messaging.incoming.orders-in.connector=smallrye-kafka
mp.messaging.incoming.orders-in.topic=order-events
mp.messaging.incoming.orders-in.auto.offset.reset=earliest

Perintah ./mvnw quarkus:add-extension -Dextensions=reactive-messaging-kafka menambahkan Kafka connector. Untuk AMQP atau MQTT, ganti connector dengan smallrye-amqp atau smallrye-mqtt.

Ketika Menggunakan Reactive vs Imperative

Kapan Memakai Imperative

  • Kode bisnis sederhana dan dominan blocking (JDBC sinkron, third-party sync).
  • Tim belum terbiasa dengan reactive dan observability mutiny.
  • Beban concurrent sedang dan latensi tidak kritis.

Kapan Memakai Reactive

  • Skala concurrent tinggi: ribuan request per detik.
  • I/O intensif: banyak panggilan eksternal, database, dan messaging.
  • Streaming data dan event-driven architecture.
  • Integrasi erat dengan Vert.x dan messaging.

Panduan Praktis

Kombinasi keduanya sah: pakai imperative untuk CRUD sederhana dan reactive untuk jalur I/O tinggi. Quarkus memudahkan transisi bertahap — resource reactive dan imperative bisa hidup berdampingan dalam satu aplikasi.

Penutup

Episode 15 membuka dunia reactive Quarkus: memahami Vert.x sebagai fondasi non-blocking, konsep Uni untuk satu hasil dan Multi untuk aliran data, reactive messaging dengan Kafka, AMQP, dan MQTT, serta panduan kapan memakai reactive dibandingkan imperative.

Inti yang harus dibawa pulang:

  • Vert.x menjadi fondasi non-blocking seluruh stack Quarkus.
  • Uni mewakili satu hasil async; Multi mewakili aliran item.
  • RESTEasy Reactive mendukung tipe Mutiny di endpoint secara langsung.
  • Reactive Messaging menghubungkan aplikasi dengan broker pesan.
  • Kafka, AMQP, dan MQTT didukung lewat connector berbeda.
  • Reactive cocok untuk beban concurrent tinggi dan I/O intensif.
  • Reactive dan imperative bisa hidup berdampingan dalam satu aplikasi.

Di episode 16 selanjutnya kita akan membahas native image dan startup optimization — Quarkus native image dengan GraalVM atau Mandrel, build time augmentation dan AOT compilation, optimasi startup dan memory, serta debugging native image dan tradeoff kompatibilitas.

Belajar Quarkus - Reactive Programming & Vert.x | Belajar Quarkus