Generation Model
tapik generation starts from compiled endpoint contracts and produces only the outputs you explicitly enable.
Today that workflow is exposed through the Gradle task tapikGenerate.
What the task does
When you run tapikGenerate, tapik:
-
scans compiled classes under the configured
basePackage, -
discovers concrete
APIimplementations, -
resolves their
HttpEndpointdeclarations into metadata, -
writes an endpoint scan report,
-
invokes the enabled generators found on the classpath.
This matters because generators are not reading stale source docs or handwritten config. They are operating on the contract the code actually compiled to.
Built-in generators
| Generator | Module | Output | Enabled by |
|---|---|---|---|
Spring |
|
Generated Kotlin client interfaces |
|
Spring |
|
Generated Kotlin server interfaces |
|
|
|
|
|
Where generated files go
tapik writes to two output roots:
-
build/generated/sources/tapik/main/kotlinfor generated Kotlin sources, -
build/generatedfor non-source outputs such asAPI.mdandtapik-endpoints.txt.
Generated Kotlin sources are added to the main Kotlin source set automatically by the Gradle plugin.
Naming controls
The root tapik extension controls the common naming surface:
tapik {
basePackage("com.acme.catalog")
generatedPackageName("generated")
endpointsSuffix("Endpoints")
springRestClient {
clientSuffix("Client")
}
springWebMvc {
serverSuffix("Server")
}
}
Those settings affect:
-
which package segment generated Kotlin files use,
-
the name of the generated endpoint container interface,
-
the aggregate client and server interface names.
How extension works
tapik generators are discovered with Java ServiceLoader.
That keeps the extension boundary straightforward:
-
Kotlin generators can contribute generated endpoint contract members,
-
direct generators can write other artifacts such as
Markdown, -
other client, server, and documentation targets can be added without changing how endpoint discovery works.
A minimal direct generator looks like this:
package com.acme.tapik
import dev.akif.tapik.plugin.TapikDirectGenerator
import dev.akif.tapik.plugin.TapikGeneratorContext
import dev.akif.tapik.plugin.metadata.HttpEndpointMetadata
import java.io.File
class EndpointCountGenerator : TapikDirectGenerator {
override val id: String = "endpoint-count"
override fun generate(
endpoints: List<HttpEndpointMetadata>,
context: TapikGeneratorContext
): Set<File> {
val output = context.outputDirectory.resolve("endpoint-count.txt")
output.writeText(endpoints.size.toString())
return setOf(output)
}
}
Then register it under META-INF/services/dev.akif.tapik.plugin.TapikGenerator:
com.acme.tapik.EndpointCountGenerator
Once that module is on the classpath, tapik can discover it through ServiceLoader just like the built-in generators.
For the built-in outputs, continue with: