diff --git a/.github/workflows/samples-kotlin-server-jdk17.yaml b/.github/workflows/samples-kotlin-server-jdk17.yaml index 32f1856207a..b66723da4b1 100644 --- a/.github/workflows/samples-kotlin-server-jdk17.yaml +++ b/.github/workflows/samples-kotlin-server-jdk17.yaml @@ -7,6 +7,7 @@ on: - 'samples/server/petstore/kotlin-server/**' - 'samples/server/petstore/kotlin-server-modelMutable/**' - 'samples/server/petstore/kotlin-springboot-*/**' + - 'samples/server/petstore/kotlin-server-required-and-nullable-properties/**' # comment out due to gradle build failure # - samples/server/petstore/kotlin-spring-default/** pull_request: @@ -15,6 +16,7 @@ on: - 'samples/server/petstore/kotlin-server/**' - 'samples/server/petstore/kotlin-server-modelMutable/**' - 'samples/server/petstore/kotlin-springboot-*/**' + - 'samples/server/petstore/kotlin-server-required-and-nullable-properties/**' # comment out due to gradle build failure # - samples/server/petstore/kotlin-spring-default/** @@ -30,6 +32,7 @@ jobs: matrix: sample: # server + - samples/server/petstore/kotlin-server-required-and-nullable-properties - samples/server/petstore/kotlin-springboot-3 - samples/server/petstore/kotlin-springboot-delegate-nodefaults - samples/server/petstore/kotlin-springboot-request-cookie diff --git a/.github/workflows/samples-kotlin-server-jdk21.yaml b/.github/workflows/samples-kotlin-server-jdk21.yaml index 18a2b82eeb9..0de80197cb7 100644 --- a/.github/workflows/samples-kotlin-server-jdk21.yaml +++ b/.github/workflows/samples-kotlin-server-jdk21.yaml @@ -4,9 +4,11 @@ on: push: paths: - 'samples/server/petstore/kotlin-server/**' + - 'samples/server/petstore/kotlin-server-required-and-nullable-properties/**' pull_request: paths: - 'samples/server/petstore/kotlin-server/**' + - 'samples/server/petstore/kotlin-server-required-and-nullable-properties/**' env: GRADLE_VERSION: '8.10' @@ -21,6 +23,7 @@ jobs: sample: - samples/server/petstore/kotlin-server/javalin-6 - samples/server/petstore/kotlin-server/ktor + - samples/server/petstore/kotlin-server-required-and-nullable-properties steps: - uses: actions/checkout@v4 - uses: actions/setup-java@v4 diff --git a/bin/configs/kotlin-server-required-nullable.yaml b/bin/configs/kotlin-server-required-nullable.yaml new file mode 100644 index 00000000000..417129633a9 --- /dev/null +++ b/bin/configs/kotlin-server-required-nullable.yaml @@ -0,0 +1,7 @@ +generatorName: kotlin-server +outputDir: samples/server/petstore/kotlin-server-required-and-nullable-properties +library: javalin6 +inputSpec: modules/openapi-generator/src/test/resources/3_0/required-and-nullable-properties.yaml +templateDir: modules/openapi-generator/src/main/resources/kotlin-server +additionalProperties: + hideGenerationTimestamp: "true" diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/data_class_req_var.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/data_class_req_var.mustache index b1c939b130b..4adcedf78cb 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-server/data_class_req_var.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-server/data_class_req_var.mustache @@ -1,4 +1,5 @@ {{#description}} /* {{{.}}} */ {{/description}} - {{>modelMutable}} {{{name}}}: {{#isEnum}}{{{classname}}}.{{{nameInPascalCase}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}} \ No newline at end of file + {{! Note that required properties may be nullable according to the OpenAPI specification. }} + {{>modelMutable}} {{{name}}}: {{#isEnum}}{{{classname}}}.{{{nameInPascalCase}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#isNullable}}?{{/isNullable}}{{#defaultValue}} = {{^isNumber}}{{{defaultValue}}}{{/isNumber}}{{#isNumber}}{{{dataType}}}("{{{defaultValue}}}"){{/isNumber}}{{/defaultValue}} \ No newline at end of file diff --git a/modules/openapi-generator/src/test/resources/3_0/required-and-nullable-properties.yaml b/modules/openapi-generator/src/test/resources/3_0/required-and-nullable-properties.yaml new file mode 100644 index 00000000000..d9b9291ab35 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/required-and-nullable-properties.yaml @@ -0,0 +1,51 @@ +# OpenAPI schemas support 4 possible combinations for properties: +# 1. nullable + required +# 2. nullable + not required +# 3. not nullable + required +# 4. not nullable + not required +# This sample contains all of them to demonstrate how they are rendered in the generated code. +# Related discussion: https://github.com/OpenAPITools/openapi-generator/issues/14765 +openapi: 3.0.3 +info: + title: Nullable Required + version: 1.0.0 +servers: + - url: /api/v3 +paths: + /pet: + post: + operationId: addPet + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + responses: + "200": + description: Successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' +components: + schemas: + Pet: + required: + - notNullable_required + - nullable_required + type: object + properties: + nullable_notRequired: + type: string + example: doggie + nullable: true + notNullable_notRequired: + type: string + example: doggie + notNullable_required: + type: string + example: doggie + nullable_required: + type: string + example: doggie + nullable: true diff --git a/samples/server/petstore/kotlin-server-required-and-nullable-properties/.openapi-generator-ignore b/samples/server/petstore/kotlin-server-required-and-nullable-properties/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/server/petstore/kotlin-server-required-and-nullable-properties/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/server/petstore/kotlin-server-required-and-nullable-properties/.openapi-generator/FILES b/samples/server/petstore/kotlin-server-required-and-nullable-properties/.openapi-generator/FILES new file mode 100644 index 00000000000..0ead574b64d --- /dev/null +++ b/samples/server/petstore/kotlin-server-required-and-nullable-properties/.openapi-generator/FILES @@ -0,0 +1,9 @@ +README.md +build.gradle.kts +gradle.properties +settings.gradle +src/main/kotlin/org/openapitools/server/Main.kt +src/main/kotlin/org/openapitools/server/apis/DefaultApi.kt +src/main/kotlin/org/openapitools/server/apis/DefaultApiService.kt +src/main/kotlin/org/openapitools/server/apis/DefaultApiServiceImpl.kt +src/main/kotlin/org/openapitools/server/models/Pet.kt diff --git a/samples/server/petstore/kotlin-server-required-and-nullable-properties/.openapi-generator/VERSION b/samples/server/petstore/kotlin-server-required-and-nullable-properties/.openapi-generator/VERSION new file mode 100644 index 00000000000..6935482704c --- /dev/null +++ b/samples/server/petstore/kotlin-server-required-and-nullable-properties/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.10.0-SNAPSHOT diff --git a/samples/server/petstore/kotlin-server-required-and-nullable-properties/README.md b/samples/server/petstore/kotlin-server-required-and-nullable-properties/README.md new file mode 100644 index 00000000000..3ea7c4e8e80 --- /dev/null +++ b/samples/server/petstore/kotlin-server-required-and-nullable-properties/README.md @@ -0,0 +1,60 @@ +# org.openapitools.server - Kotlin Server library for Nullable Required + +No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + +Generated by OpenAPI Generator 7.10.0-SNAPSHOT. + +## Build + +First, create the gradle wrapper script: + +``` +gradle wrapper +``` + +Then, run: + +``` +./gradlew check assemble +``` + +This runs all tests and packages the library. + +## Running + +The server builds as a fat jar with a main entrypoint. To start the service, run `java -jar ./build/libs/kotlin-server.jar`. + +You may also run in docker: + +``` +docker build -t kotlin-server . +docker run -p 8080:8080 kotlin-server +``` + +## Features/Implementation Notes + +* Supports JSON inputs/outputs, File inputs, and Form inputs (see ktor documentation for more info). +* ~Supports collection formats for query parameters: csv, tsv, ssv, pipes.~ +* Some Kotlin and Java types are fully qualified to avoid conflicts with types defined in OpenAPI definitions. + + +## Documentation for API Endpoints + +All URIs are relative to */api/v3* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +*DefaultApi* | [**addPet**](docs/DefaultApi.md#addpet) | **POST** /pet | + + + +## Documentation for Models + + - [org.openapitools.server.models.Pet](docs/Pet.md) + + + +## Documentation for Authorization + +Endpoints do not require authorization. + diff --git a/samples/server/petstore/kotlin-server-required-and-nullable-properties/build.gradle.kts b/samples/server/petstore/kotlin-server-required-and-nullable-properties/build.gradle.kts new file mode 100644 index 00000000000..220ec0c53ac --- /dev/null +++ b/samples/server/petstore/kotlin-server-required-and-nullable-properties/build.gradle.kts @@ -0,0 +1,33 @@ +plugins { + kotlin("jvm") version "2.0.21" +} + +group = "org.openapitools" +version = "1.0.0" + +kotlin { + jvmToolchain(21) +} + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(21)) + } +} + +repositories { + mavenCentral() +} + +dependencies { + implementation("io.javalin:javalin:6.1.6") + implementation("com.fasterxml.jackson.core:jackson-databind:2.17.1") + implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.17.1") + implementation("org.slf4j:slf4j-simple:2.0.13") + + testImplementation("org.jetbrains.kotlin:kotlin-test") +} + +tasks.test { + useJUnitPlatform() +} diff --git a/samples/server/petstore/kotlin-server-required-and-nullable-properties/gradle.properties b/samples/server/petstore/kotlin-server-required-and-nullable-properties/gradle.properties new file mode 100644 index 00000000000..5f1ed7bbe02 --- /dev/null +++ b/samples/server/petstore/kotlin-server-required-and-nullable-properties/gradle.properties @@ -0,0 +1 @@ +org.gradle.caching=true \ No newline at end of file diff --git a/samples/server/petstore/kotlin-server-required-and-nullable-properties/settings.gradle b/samples/server/petstore/kotlin-server-required-and-nullable-properties/settings.gradle new file mode 100644 index 00000000000..a09a58efab1 --- /dev/null +++ b/samples/server/petstore/kotlin-server-required-and-nullable-properties/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'kotlin-server' \ No newline at end of file diff --git a/samples/server/petstore/kotlin-server-required-and-nullable-properties/src/main/kotlin/org/openapitools/server/Main.kt b/samples/server/petstore/kotlin-server-required-and-nullable-properties/src/main/kotlin/org/openapitools/server/Main.kt new file mode 100644 index 00000000000..6ad8a4dffc1 --- /dev/null +++ b/samples/server/petstore/kotlin-server-required-and-nullable-properties/src/main/kotlin/org/openapitools/server/Main.kt @@ -0,0 +1,21 @@ +package org.openapitools.server + +import io.javalin.Javalin +import io.javalin.apibuilder.ApiBuilder.* + +import org.openapitools.server.apis.DefaultApi +import org.openapitools.server.apis.DefaultApiServiceImpl + +fun main() { + val defaultApi = DefaultApi(DefaultApiServiceImpl()) + + val app = Javalin + .create { config -> + config.router.apiBuilder { + path("/pet") { post(defaultApi::addPet) } + + } + } + + app.start() +} diff --git a/samples/server/petstore/kotlin-server-required-and-nullable-properties/src/main/kotlin/org/openapitools/server/apis/DefaultApi.kt b/samples/server/petstore/kotlin-server-required-and-nullable-properties/src/main/kotlin/org/openapitools/server/apis/DefaultApi.kt new file mode 100644 index 00000000000..f2986b9a019 --- /dev/null +++ b/samples/server/petstore/kotlin-server-required-and-nullable-properties/src/main/kotlin/org/openapitools/server/apis/DefaultApi.kt @@ -0,0 +1,20 @@ +package org.openapitools.server.apis + +import io.javalin.http.Context +import io.javalin.http.bodyAsClass +import io.javalin.http.pathParamAsClass +import io.javalin.http.queryParamAsClass + +import org.openapitools.server.models.Pet + +class DefaultApi(private val service: DefaultApiService) { + /** + * + * @param pet (optional) + */ + fun addPet(ctx: Context) { + val result = service.addPet(ctx.bodyAsClass(), ctx) + ctx.status(200).json(result) + } + +} diff --git a/samples/server/petstore/kotlin-server-required-and-nullable-properties/src/main/kotlin/org/openapitools/server/apis/DefaultApiService.kt b/samples/server/petstore/kotlin-server-required-and-nullable-properties/src/main/kotlin/org/openapitools/server/apis/DefaultApiService.kt new file mode 100644 index 00000000000..7d177214bfe --- /dev/null +++ b/samples/server/petstore/kotlin-server-required-and-nullable-properties/src/main/kotlin/org/openapitools/server/apis/DefaultApiService.kt @@ -0,0 +1,17 @@ +package org.openapitools.server.apis + +import org.openapitools.server.models.Pet +import io.javalin.http.Context + +interface DefaultApiService { + + /** + * POST /pet + * + * @param pet (optional) + * @param ctx The Javalin context. Especially handy if you need to access things like authentication headers in your service. (required) + * @return Successful operation (status code 200) + * @see DefaultApi#addPet + */ + fun addPet(pet: Pet?, ctx: Context): Pet +} diff --git a/samples/server/petstore/kotlin-server-required-and-nullable-properties/src/main/kotlin/org/openapitools/server/apis/DefaultApiServiceImpl.kt b/samples/server/petstore/kotlin-server-required-and-nullable-properties/src/main/kotlin/org/openapitools/server/apis/DefaultApiServiceImpl.kt new file mode 100644 index 00000000000..883452e3286 --- /dev/null +++ b/samples/server/petstore/kotlin-server-required-and-nullable-properties/src/main/kotlin/org/openapitools/server/apis/DefaultApiServiceImpl.kt @@ -0,0 +1,11 @@ +package org.openapitools.server.apis + +import org.openapitools.server.models.Pet +import io.javalin.http.Context + +class DefaultApiServiceImpl : DefaultApiService { + + override fun addPet(pet: Pet?, ctx: Context): Pet { + TODO("Implement me") + } +} diff --git a/samples/server/petstore/kotlin-server-required-and-nullable-properties/src/main/kotlin/org/openapitools/server/models/Pet.kt b/samples/server/petstore/kotlin-server-required-and-nullable-properties/src/main/kotlin/org/openapitools/server/models/Pet.kt new file mode 100644 index 00000000000..8dddb90062b --- /dev/null +++ b/samples/server/petstore/kotlin-server-required-and-nullable-properties/src/main/kotlin/org/openapitools/server/models/Pet.kt @@ -0,0 +1,28 @@ +/** + * Nullable Required + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. +*/ +package org.openapitools.server.models + + +/** + * + * @param notNullableRequired + * @param nullableRequired + * @param nullableNotRequired + * @param notNullableNotRequired + */ +data class Pet( + val notNullableRequired: kotlin.String, + val nullableRequired: kotlin.String?, + val nullableNotRequired: kotlin.String? = null, + val notNullableNotRequired: kotlin.String? = null +) +