Skip to content
KAP

KAP

Type-safe multi-service orchestration for Kotlin coroutines.
Flat chains, visible phases, compiler-checked argument order.

Get Started GitHub


The Problem

You have 11 microservice calls. Some run in parallel, others depend on earlier results. With raw coroutines you get invisible phases, silent bugs, and 30+ lines of boilerplate:

val checkout = coroutineScope {
    val dUser = async { fetchUser() }
    val dCart = async { fetchCart() }
    val dPromos = async { fetchPromos() }
    val dInventory = async { fetchInventory() }
    val user = dUser.await()      // ← move this above async? Silent serialization.
    val cart = dCart.await()       // ← swap with promos? Same type, no compiler error.
    val promos = dPromos.await()
    val inventory = dInventory.await()
    // ... 20 more lines of shuttle variables
}

The Solution

val checkout: CheckoutResult = Async {
    kap(::CheckoutResult)
        .with { fetchUser() }              // ┐
        .with { fetchCart() }               // ├─ phase 1: parallel
        .with { fetchPromos() }             // │
        .with { fetchInventory() }          // ┘
        .then { validateStock() }           // ── phase 2: barrier
        .with { calcShipping() }            // ┐
        .with { calcTax() }                 // ├─ phase 3: parallel
        .with { calcDiscounts() }           // ┘
        .then { reservePayment() }          // ── phase 4: barrier
        .with { generateConfirmation() }    // ┐ phase 5: parallel
        .with { sendEmail() }              // ┘
}

11 service calls. 5 phases. One flat chain. Swap any two .with lines and the compiler rejects it. 130ms total vs 460ms sequential.


Visible Phases

.with = parallel, .then = barrier. The code shape is the execution plan. No guessing where phases begin and end.

Compile-Time Safety

Each .with slot is typed. Swap two same-type services? The compiler catches it. No positional bugs.

Zero Overhead

JMH benchmarks show KAP overhead is indistinguishable from raw coroutines. No reflection, no code generation at runtime.

Multiplatform

JVM, JS, iOS, macOS, Linux. One dependency: kotlinx-coroutines-core.

Resilience Built-In

Schedule, CircuitBreaker, Resource, bracket, timeoutRace, raceQuorum. All composable in the chain.

Arrow Integration

Parallel validation with error accumulation. zipV scales to 22 validators (Arrow maxes at 9).


Modules

Pick what you need:

Module What you get Depends on
kap-core Kap, with, then, race, traverse, memoize, timeout, recover kotlinx-coroutines-core
kap-resilience Schedule, CircuitBreaker, Resource, bracket, timeoutRace, raceQuorum kap-core
kap-arrow zipV, withV, validated {}, attempt(), raceEither kap-core + Arrow
dependencies {
    implementation("io.github.damian-rafael-lattenero:kap-core:2.3.0")

    // Optional
    implementation("io.github.damian-rafael-lattenero:kap-resilience:2.3.0")
    implementation("io.github.damian-rafael-lattenero:kap-arrow:2.3.0")
}

Benchmarks

All claims backed by 119 JMH benchmarks and deterministic virtual-time proofs.

Dimension Raw Coroutines Arrow KAP
Framework overhead (arity 3) <0.01ms 0.02ms <0.01ms
Multi-phase (9 calls, 4 phases) 180.85ms 181.06ms 180.98ms
timeoutRace (primary wins) 180.55ms -- 30.34ms
Max validation arity -- 9 22

Live benchmark dashboard