Generate a Server
The server generator targets Spring Web MVC.
Use it when you want Spring controller interfaces to stay aligned with the same tapik contract that also drives clients and documentation.
Use dev.akif.tapik:spring-webmvc to enable it.
Enable the generator
dependencies {
implementation("dev.akif.tapik:spring-webmvc:<version>")
}
tapik {
springWebMvc { }
}
If you want a different generated suffix:
tapik {
springWebMvc {
serverSuffix("Api")
}
}
What gets generated
The generator contributes Kotlin source files under:
-
build/generated/sources/tapik/main/kotlin/<package>/…
For each source file of endpoint declarations, tapik generates:
-
an aggregate server interface such as
CatalogApiServer, -
one nested server contract per endpoint,
-
one generated response model per endpoint.
interface CatalogApiServer : CatalogApiEndpoints.GetProduct.Server
interface CatalogApiEndpoints {
interface GetProduct {
sealed class Response(open val status: Status) {
data class Ok(
val body: ProductView
) : Response(Status.Ok)
data class NotFound(
val body: ProblemDetails
) : Response(Status.NotFound)
}
interface Server {
@org.springframework.web.bind.annotation.GetMapping(path = ["/api/v1/products/{productId}"])
fun getProduct(
@org.springframework.web.bind.annotation.PathVariable(name = "productId") productId: String,
@org.springframework.web.bind.annotation.RequestHeader(name = "X-Request-Id") xRequestId: java.util.UUID
): Response
}
}
}
The exact generated code varies with the contract, but the behavior is consistent:
-
method and path come from the endpoint definition,
-
query parameters, headers, and request bodies map to the matching Spring annotations,
-
multi-output endpoints keep distinct response variants.
How Spring mapping is derived
The generator uses the endpoint contract to choose the mapping form:
-
standard verbs such as
GETandPOSTuse the corresponding Spring mapping annotations, -
nonstandard verbs such as
HEADfall back to@RequestMappingwith an explicit request method, -
media types come from the declared input and output bodies,
-
fixed response headers and typed bodies are reflected in the generated response model.
Implement the generated contract
Your application still owns the controller implementation:
@org.springframework.web.bind.annotation.RestController
class CatalogController : CatalogApiServer {
override fun getProduct(
productId: String,
xRequestId: java.util.UUID
): CatalogApiEndpoints.GetProduct.Response = TODO()
}
This keeps the transport contract generated while leaving your business logic, persistence, and orchestration code handwritten.
Boundaries
The server generator does not:
-
register controllers for you,
-
implement endpoint logic,
-
turn tapik into a full Spring application framework.
It generates the transport-facing interface and response model. Your application provides the actual behavior.