agentsclimarketplace

Kora openapi generator server

Skill kora-projects/kora-skills/plugins/kora-v1/skills/kora-openapi-generator-server

Agent Skills for Kora Framework — compile-time DI for Java/Kotlin backend development.

Install
npx -y skills add kora-projects/kora-skills --skill kora-openapi-generator-server

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Generates Kora HTTP server code from OpenAPI 3.x contracts with the kora generator of the org.openapi.generator Gradle plugin. Produces a generated *ApiController, an *ApiDelegate interface implemented with @Component, sealed *ApiResponses wrappers (one record per status code), and model records. Use when scaffolding a contract-first Kora HTTP server, choosing the server mode (java-server, java-async-server, java-reactive-server, kotlin-server, kotlin-suspend-server), enabling enableServerValidation, wiring HttpServerPrincipalExtractor for securitySchemes, handling oneOf/allOf discriminators with openapiNormalizer DISABLE_ALL, or exposing /openapi and /swagger-ui via OpenApiManagementModule. Requires the http-server-undertow module plus the Kora annotation processor (annotation-processors) or KSP (symbol-processors).

SKILL.md

13.5 KB, as published. Nobody here has run it

Kora OpenAPI Generator — HTTP Server

Generate a type-safe Kora HTTP server from an OpenAPI 3.x contract. The kora generator emits the transport layer (controller, response wrappers, models); you implement one generated *ApiDelegate interface with @Component and return the generated sealed *ApiResponses records. The generated controller registers routes automatically — never write @HttpController/@HttpRoute by hand for a generated API, and never edit files under build/generated/.

All Kora artifacts inherit their version from the kora-parent BOM (ru.tinkoff.kora:kora-parent, e.g. 1.2.17 in the example apps) — never pin a version on an individual ru.tinkoff.kora:* dependency. The OpenAPI plugin org.openapi.generator is pinned to 7.14.0; other versions are not guaranteed to be code-compatible.

Quick Start

1. Dependencies

===! ":fontawesome-brands-java: Java"

```groovy title="build.gradle"
import org.openapitools.generator.gradle.plugin.tasks.GenerateTask

buildscript {
    dependencies {
        classpath("ru.tinkoff.kora:openapi-generator:$koraVersion")
    }
}

plugins {
    id "java"
    id "application"
    id "org.openapi.generator" version "7.14.0"
}

configurations {
    koraBom
    annotationProcessor.extendsFrom(koraBom)
    implementation.extendsFrom(koraBom)
}

dependencies {
    koraBom platform("ru.tinkoff.kora:kora-parent:$koraVersion")
    annotationProcessor "ru.tinkoff.kora:annotation-processors"

    implementation "ru.tinkoff.kora:http-server-undertow"
    implementation "ru.tinkoff.kora:json-module"
    implementation "ru.tinkoff.kora:config-hocon"
    implementation "ru.tinkoff.kora:logging-logback"
    implementation "ru.tinkoff.kora:openapi-management"   // serves /openapi + /swagger-ui
    implementation "ru.tinkoff.kora:validation-module"    // needed for enableServerValidation
}
```

=== ":simple-kotlin: Kotlin"

```kotlin title="build.gradle.kts"
import org.openapitools.generator.gradle.plugin.tasks.GenerateTask

buildscript {
    dependencies {
        classpath("ru.tinkoff.kora:openapi-generator:$koraVersion")
    }
}

plugins {
    kotlin("jvm") version "1.9.24"
    id("application")
    id("org.openapi.generator") version "7.14.0"
    id("com.google.devtools.ksp") version "1.9.24-1.0.20"
}

configurations {
    koraBom
    ksp.extendsFrom(koraBom)
    implementation.extendsFrom(koraBom)
}

dependencies {
    koraBom(platform("ru.tinkoff.kora:kora-parent:$koraVersion"))
    ksp("ru.tinkoff.kora:symbol-processors")

    implementation("ru.tinkoff.kora:http-server-undertow")
    implementation("ru.tinkoff.kora:json-module")
    implementation("ru.tinkoff.kora:config-yaml")
    implementation("ru.tinkoff.kora:logging-logback")
    implementation("ru.tinkoff.kora:openapi-management")
    implementation("ru.tinkoff.kora:validation-module")
}
```

2. Generation task

===! ":fontawesome-brands-java: Java"

```groovy title="build.gradle"
def openApiGenerateHttpServer = tasks.register("openApiGenerateHttpServer", GenerateTask) {
    generatorName = "kora"
    group = "openapi tools"
    inputSpec = "$projectDir/src/main/resources/openapi/user-api.yaml"
    outputDir = "$buildDir/generated/user-api-server"   // unique per API
    def corePackage = "com.example.userapi"
    apiPackage = "${corePackage}.api"
    modelPackage = "${corePackage}.model"
    invokerPackage = "${corePackage}.invoker"
    openapiNormalizer = [DISABLE_ALL: "true"]           // keeps oneOf/allOf intact
    configOptions = [
        mode                  : "java-server",
        enableServerValidation: "true",
    ]
}
sourceSets.main { java.srcDirs += openApiGenerateHttpServer.get().outputDir }
compileJava.dependsOn openApiGenerateHttpServer
```

=== ":simple-kotlin: Kotlin"

```kotlin title="build.gradle.kts"
val openApiGenerateHttpServer = tasks.register<GenerateTask>("openApiGenerateHttpServer") {
    generatorName = "kora"
    group = "openapi tools"
    inputSpec = "$projectDir/src/main/resources/openapi/user-api.yaml"
    outputDir = "$buildDir/generated/user-api-server"   // unique per API
    val corePackage = "com.example.userapi"
    apiPackage = "$corePackage.api"
    modelPackage = "$corePackage.model"
    invokerPackage = "$corePackage.invoker"
    openapiNormalizer = mapOf("DISABLE_ALL" to "true")
    configOptions = mapOf(
        "mode" to "kotlin-server",
        "enableServerValidation" to "true",
    )
}
kotlin.sourceSets.main { kotlin.srcDir(openApiGenerateHttpServer.get().outputDir) }
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KspTask> {
    dependsOn(openApiGenerateHttpServer)
}
```

3. Plug the modules into @KoraApp

@KoraApp
public interface Application extends
        HoconConfigModule,
        LogbackModule,
        JsonModule,
        ValidationModule,             // only if enableServerValidation = true
        UndertowHttpServerModule,
        OpenApiManagementModule {     // exposes /openapi + /swagger-ui

    static void main(String[] args) {
        KoraApplication.run(ApplicationGraph::graph);
    }
}

KoraApplication is ru.tinkoff.kora.application.graph.KoraApplication.

4. Implement the generated delegate

The generator emits UsersApiDelegate (one method per operationId) and UsersApiResponses (one sealed interface per operation, one record per declared status). Implement the delegate, returning the matching response record.

For advanced codegen options (requestInDelegateParams, oneOf handling, enableServerValidation), see Advanced Codegen Options.

===! ":fontawesome-brands-java: Java"

```java
package com.example.userapi.controller;

import ru.tinkoff.kora.common.Component;
import com.example.userapi.api.UsersApiDelegate;
import com.example.userapi.api.UsersApiResponses;
import com.example.userapi.model.ErrorResponseTO;

@Component
public final class UserApiDelegateImpl implements UsersApiDelegate {

    private final UserService userService;

    public UserApiDelegateImpl(UserService userService) {
        this.userService = userService;
    }

    @Override
    public UsersApiResponses.GetUserApiResponse getUser(String userId) {
        return userService.findById(userId)
            .<UsersApiResponses.GetUserApiResponse>map(user ->
                new UsersApiResponses.GetUserApiResponse.GetUser200ApiResponse(toTO(user)))
            .orElseGet(() ->
                new UsersApiResponses.GetUserApiResponse.GetUser404ApiResponse(
                    new ErrorResponseTO("User not found: " + userId)));
    }
}
```

=== ":simple-kotlin: Kotlin"

```kotlin
package com.example.userapi.controller

import ru.tinkoff.kora.common.Component
import com.example.userapi.api.UsersApiDelegate
import com.example.userapi.api.UsersApiResponses
import com.example.userapi.model.ErrorResponseTO

@Component
class UserApiDelegateImpl(
    private val userService: UserService
) : UsersApiDelegate {

    override fun getUser(userId: String): UsersApiResponses.GetUserApiResponse =
        userService.findById(userId)
            ?.let { UsersApiResponses.GetUserApiResponse.GetUser200ApiResponse(it.toTO()) }
            ?: UsersApiResponses.GetUserApiResponse.GetUser404ApiResponse(
                ErrorResponseTO("User not found: $userId"))
}
```

5. Build and run

./gradlew clean classes   # runs the generator, then compiles
./gradlew run

Server modes

Set via configOptions.mode. The delegate method's return type follows the mode.

ModeDelegate return typeNotes
java-server*ApiResponses.*ApiResponseSynchronous (recommended start)
java-async-serverCompletionStage<*ApiResponse>Non-blocking
java-reactive-serverMono<*ApiResponse>Add io.projectreactor:reactor-core yourself
kotlin-server*ApiResponses.*ApiResponseSynchronous Kotlin
kotlin-suspend-serversuspend fun ... : *ApiResponseCoroutine-based

Core rules

  1. Implement *ApiDelegate only. It is the single implementation point. The *ApiController and *ApiResponses are generated — do not touch them.
  2. Return the generated sealed *ApiResponses record, never a raw DTO. There is no ResponseEntity in Kora.
  3. A response record exists only for a status declared in the contract. If you need a GetUser500ApiResponse, declare "500" under that operation's responses.
  4. @Component makes the delegate discoverable by the compile-time graph. Keep business logic in services; the delegate maps between generated transport models and your internal DTOs.
  5. openapiNormalizer = [DISABLE_ALL: "true"] when using oneOf/allOf — since plugin 7.0.0 the SIMPLIFY_ONEOF_ANYOF rule rewrites polymorphic schemas.
  6. oneOf without discriminator collapses to empty record in 7.14.0 — flatten to single schema with nullable fields, or add explicit discriminator (see Advanced Codegen).

Common pitfalls

SymptomFix
Delegate not discovered ("required dependency not found")Add @Component; confirm it implements the generated *ApiDelegate from your apiPackage.
Wrong return type / compile errorReturn *ApiResponses.<Op><Status>ApiResponse, not a DTO or ResponseEntity.
Generated classes missingRegister outputDir in sourceSets.main and add compileJava.dependsOn (Java) / KspTask dependsOn (Kotlin).
Discriminator collapsed to a single typeSet openapiNormalizer = [DISABLE_ALL: "true"].
Validation annotations absentSet enableServerValidation: "true" and add validation-module + ValidationModule.
Two tasks overwrite each otherGive each generator task a unique outputDir.
/swagger-ui missingAdd OpenApiManagementModule and enable openapi.management in config.
oneOf without discriminator generates empty recordKora generator 7.14.0 bug — flatten to single schema with nullable fields, or add discriminator (see Advanced Codegen)
Need raw HttpServerRequest in delegateSet requestInDelegateParams: "true" (see Advanced Codegen)

References

DocumentCovers
Codegen ReferenceFull configOptions table, modes, normalizer
Delegates Reference*ApiDelegate shapes, sync/async/reactive/suspend, requestInDelegateParams, delegateMethodBodyMode
Response ReferenceSealed *ApiResponses records, headers, 204, status selection
Controllers ReferenceGenerated controller, prefixPath, interceptors, validation interceptor
Models ReferenceGenerated records, enums, dates, JsonNullable, discriminators
Validation ReferenceKora validation annotations from schema constraints
Authorization ReferencesecuritySchemesHttpServerPrincipalExtractor + ApiSecurity tags

Source of truth: openapi-codegen.md, guides openapi-http-server.md and openapi-http-server-advanced.md.

Assets

AssetPurpose
assets/build.gradle.server.template / assets/build.gradle.kts.server.templateAnnotated build config for server generation
assets/Application.server.java.template / .kt.template@KoraApp with OpenAPI management + validation
assets/PetApiDelegate.server.java.template / .kt.templateDelegate implementation example
assets/openapi-spec.yaml.templateFull OpenAPI 3.x spec with CRUD + discriminators
assets/templates/Reusable spec snippets, delegate and response patterns
scripts/validate_openapi.pyPre-generation spec sanity check

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.