Building a feature
Add a feature the way the platform does. A model, a repository, a service, and a controller — each a few annotated lines, each wired into the running server. Here is the whole slice.
1 · Model
A plain Kotlin data class in the core module — the one shape your feature is about. It's just the data; the repository, service, and API you build next give it behavior.
data class Task(
val id: UUID,
val title: String,
val status: TaskStatus,
)2 · Repository
Annotate a class @Repository and write your queries as raw SQL with named parameters. The processor generates the JDBC — the statement, the parameter binding, the row mapping to your model — as a suspending function. You write the SQL; the rest is generated.
:named parameters, mapped to your model.@Repository
class TaskRepository {
@Query("SELECT * FROM tasks WHERE status = :status")
suspend fun byStatus(status: TaskStatus): List<Task>
}3 · Service
@ServiceImplementation registers your service with the container, its dependencies injected through the constructor. The service is the boundary every caller goes through — controllers and other subsystems talk to it, never to the repository directly.
@ServiceImplementation
class TaskServiceImpl(
private val tasks: TaskRepository,
) : TaskService {
override suspend fun open() =
tasks.byStatus(TaskStatus.OPEN)
}4 · API
Declare the type in the schema, then bind a controller with @TypeController and @Field — your fields join the one schema every subsystem shares. Prefer REST? Annotate a handler @RouteController with its path, method, and authentication. Either way, the endpoint is live in the same server.
@TypeController("Query")
class TaskController(
private val tasks: TaskService,
) {
@Field
suspend fun openTasks() = tasks.open()
}Keep exploring