Generate Kotlin DTOs from one interface
KReplica is a KSP plugin that creates type-safe sealed hierarchies for Create, Data, and Patch variants—eliminating boilerplate and runtime surprises.
package io.availe.demo
import io.availe.Replicate
import io.availe.models.DtoVariant
import kotlinx.serialization.Serializable
import kotlin.time.ExperimentalTime
import kotlin.time.Instant
import kotlin.uuid.ExperimentalUuidApi
import kotlin.uuid.Uuid
@OptIn(ExperimentalUuidApi::class, ExperimentalTime::class)
@Replicate.Apply([Serializable::class])
@Replicate.Model(variants = [DtoVariant.DATA, DtoVariant.CREATE, DtoVariant.PATCH])
private interface UserAccount {
@Replicate.Property(include = [DtoVariant.DATA])
val id: Uuid
val email: String
val lastLogin: Instant
val sessionTokens: SessionTokens
}
// KReplica is flexible, you can use whatever types you wish
@JvmInline
value class SessionTokens(val value: List<String>)
// Generated by KReplica. Do not edit.
@file:OptIn(ExperimentalUuidApi::class, ExperimentalTime::class)
package io.availe.demo
import io.availe.models.KReplicaCreateVariant
import io.availe.models.KReplicaDataVariant
import io.availe.models.KReplicaPatchVariant
import io.availe.models.SerializablePatchable
import kotlin.OptIn
import kotlin.String
import kotlin.time.ExperimentalTime
import kotlin.time.Instant
import kotlin.uuid.ExperimentalUuidApi
import kotlin.uuid.Uuid
import kotlinx.serialization.Contextual
import kotlinx.serialization.Serializable
/**
* A sealed hierarchy representing all variants of the UserAccount data model.
*/
@Serializable
public sealed interface UserAccountSchema {
@Serializable
public data class Data(
public val id: Uuid,
public val email: String,
public val lastLogin: @Contextual Instant,
public val sessionTokens: @Contextual SessionTokens,
) : UserAccountSchema,
KReplicaDataVariant<UserAccountSchema>
@Serializable
public data class CreateRequest(
public val email: String,
public val lastLogin: @Contextual Instant,
public val sessionTokens: @Contextual SessionTokens,
) : UserAccountSchema,
KReplicaCreateVariant<UserAccountSchema>
@Serializable
public data class PatchRequest(
public val email: SerializablePatchable<String> = SerializablePatchable.Unchanged,
public val lastLogin:
SerializablePatchable<@Contextual Instant> = SerializablePatchable.Unchanged,
public val sessionTokens:
SerializablePatchable<@Contextual SessionTokens> = SerializablePatchable.Unchanged,
) : UserAccountSchema,
KReplicaPatchVariant<UserAccountSchema>
}
- Generates Create, Data & Patch from one interface.
-
Sealed hierarchies allow exhaustive
when
expressions. - Generate versioned DTOs with ease.
- Compile-time codegen powered via KSP and Kotlin Poet.
Bulletproof Your APIs
KReplica uses sealed hierarchies to enable exhaustive when
expressions. If you add a new API
version, your code won't compile until you handle all cases.
fun handleAllDataVariants(data: UserAccountSchema.DataVariant) {
when (data) {
is UserAccountSchema.V1.Data -> println("Handle V1 Data: ${data.id}")
is UserAccountSchema.V2.Data -> println("Handle V2 Data: ${data.email}")
}
}
fun handleV2Variants(user: UserAccountSchema.V2) {
when (user) {
is UserAccountSchema.V2.CreateRequest -> println("Handle V2 Create: ${user.email}")
is UserAccountSchema.V2.Data -> println("Handle V2 Data: ${user.id}")
is UserAccountSchema.V2.PatchRequest -> println("Handle V2 Patch")
}
}
fun handleAllUserTypes(user: UserAccountSchema) {
when (user) {
is UserAccountSchema.V1.CreateRequest -> println("Handle V1 Create")
is UserAccountSchema.V1.Data -> println("Handle V1 Data")
is UserAccountSchema.V1.PatchRequest -> println("Handle V1 Patch")
is UserAccountSchema.V2.CreateRequest -> println("Handle V2 Create")
is UserAccountSchema.V2.Data -> println("Handle V2 Data")
is UserAccountSchema.V2.PatchRequest -> println("Handle V2 Patch")
}
}
Setup
Add the KSP and KReplica plugins to your module's build.gradle.kts
file to start generating DTOs
automatically.
plugins {
// Use a KSP version compatible with your Kotlin version
id("com.google.devtools.ksp") version "2.2.20-2.0.3"
id("io.availe.kreplica") version "5.0.4"
}