Quickstart

This walkthrough gets you from zero to one generated result with the smallest useful tapik setup.

This example uses:

  • the Gradle plugin,

  • the core contract DSL,

  • Jackson-backed JSON bodies,

  • the Spring RestClient generator,

  • the Markdown documentation generator.

1. Add the plugin and dependencies

Apply the Gradle plugin to the module that owns your endpoint contracts:

plugins {
    kotlin("jvm")
    id("dev.akif.tapik.plugin.gradle") version "<version>"
}

dependencies {
    implementation("dev.akif.tapik:core:<version>")
    implementation("dev.akif.tapik:jackson:<version>")
    implementation("dev.akif.tapik:spring-restclient:<version>")
}

Add dev.akif.tapik:spring-webmvc:<version> only if you also want generated Spring Web MVC server interfaces.

Both Spring integration modules bring their shared Spring support transitively through dev.akif.tapik:common-spring, so you do not need to declare that module separately for normal usage.

2. Enable generation

tapik scans compiled classes under one base package and runs only the generators you enable:

tapik {
    basePackage("com.acme.catalog")

    springRestClient { }
    markdownDocumentation { }
}

For this first run:

  • basePackage tells tapik where to look for API implementations,

  • springRestClient { } turns on typed client generation,

  • markdownDocumentation { } writes a Markdown summary of the discovered endpoints.

3. Declare one endpoint

Create an API type under the configured base package:

package com.acme.catalog

import dev.akif.tapik.*
import dev.akif.tapik.jackson.jsonBody

data class ProductView(
    val id: String,
    val name: String,
    val status: String
)

data class ProblemDetails(
    val code: String,
    val message: String
)

object CatalogApi : API {
    private val products = "api" / "v1" / "products"
    private val productId = path.string("productId")
    private val locale = query.string("locale").optional("en-US")

    val getProduct by endpoint(
        description = "Get a product by ID",
        details = "Returns localized product data when the product exists."
    ) {
        get(products / productId + locale)
            .input(header.uuid("X-Request-Id"))
            .output(Status.Ok) { jsonBody<ProductView>("product") }
            .output(Status.NotFound) { jsonBody<ProblemDetails>("problem") }
    }
}

This one declaration is enough for tapik to understand:

  • the HTTP method and URI template,

  • the required path, query, and header inputs,

  • the response branches the endpoint may produce,

  • the summary text that should appear in generated documentation.

4. Run tapik

./gradlew tapikGenerate

The task compiles the project, scans the configured package, builds endpoint metadata, and runs the enabled generators.

5. Inspect the generated files

After the task completes, look at:

Output Location

Generated Kotlin sources

build/generated/sources/tapik/main/kotlin/…​

Generated Markdown summary

build/generated/API.md

Endpoint scan report

build/generated/tapik-endpoints.txt

Generated Kotlin sources are added to the main source set automatically.

6. Use the generated client

With spring-restclient enabled, tapik generates a client interface that only needs a Spring RestClient:

@org.springframework.stereotype.Component
class HttpCatalogClient(
    override val restClient: org.springframework.web.client.RestClient
) : CatalogApiClient

The generated method signature is derived from the endpoint contract, including path parameters, query defaults, headers, and response variants.

What to do next

If this quickstart matches your use case, continue based on the next problem you want to solve: