kotlinquarkusquarkus-qute

Type-safe Qute template with Kotlin data classes


I'm learning Quarkus and Qute with Kotlin, but I can't get type-safe templates to work.

The data I'm feeding into my template is of type Paginated<out T> (where Paginated adds information about total page count, current page, etc.).

The documentation says you can let your controller return

a Java record that implements io.quarkus.qute.TemplateInstance

And I was hoping that I could do the same thing with a Kotlin data class. I prefer that over invoking an @JvmStatic external fun method since the latter is a lot harder to write unit tests for.

Anyway, I wrote a controller that returns this data class instance:

@GET @Path("/list") @Produces(MediaType.TEXT_HTML)
fun list(@QueryParam("pageIndex") pageIndex: Int = 0): TemplateInstance {
  // work your magic
  return ExampleListTemplate(
    Paginated(
      currentPage = 0,
      pageCount = 1,
      items = listOf("example")
    )
  )
}

@CheckedTemplate(basePath = "example")
data class ExampleListTemplate(val data: Paginated<String>): TemplateInstance

But when I request that page, I get a stacktrace:

Caused by: java.lang.UnsupportedOperationException
    at io.quarkus.qute.TemplateInstance.getTemplate(TemplateInstance.java:142)
    at io.quarkus.resteasy.qute.runtime.TemplateResponseFilter.filter(TemplateResponseFilter.java:45)

The actual one is a lot longer but I believe this is the relevant part.

Is this supposed to work? If so, what am I doing wrong?


Solution

  • Annotating a Kotlin data class with @JvmRecord tells the Kotlin compiler to mark the class as a Java record and generate relevant toString/equals/hashCode methods.

    It turns out that this is also enough for Quarkus to leverage that Kotlin data class as a TemplateInstance.

    With a data class written like so:

    @CheckedTemplate(basePath = "example")
    @JvmRecord
    data class List(val data: Paginated<String>): TemplateInstance
    

    Quarkus will look for a template example/list.html.