From 4a5ec7c9b459939b54936ced972477797e482334 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Kozak?= Date: Tue, 3 Mar 2026 13:27:07 +0100 Subject: [PATCH 1/5] [kotlin] Add = null default for optional parameters in jvm-ktor and javalin templates Fixes #23100 Several Kotlin templates made optional parameters nullable (Type?) but did not assign = null as a default value, forcing callers to explicitly pass null for every optional parameter instead of omitting them. Updated templates: - kotlin-client/libraries/jvm-ktor/api.mustache - kotlin-server/libraries/javalin5/service.mustache - kotlin-server/libraries/javalin5/serviceImpl.mustache - kotlin-server/libraries/javalin6/service.mustache - kotlin-server/libraries/javalin6/serviceImpl.mustache Co-Authored-By: Claude Opus 4.6 --- .../resources/kotlin-client/libraries/jvm-ktor/api.mustache | 2 +- .../resources/kotlin-server/libraries/javalin5/service.mustache | 2 +- .../kotlin-server/libraries/javalin5/serviceImpl.mustache | 2 +- .../resources/kotlin-server/libraries/javalin6/service.mustache | 2 +- .../kotlin-server/libraries/javalin6/serviceImpl.mustache | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-ktor/api.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-ktor/api.mustache index 03efece88e47..bff6f9ff53ea 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-ktor/api.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-ktor/api.mustache @@ -52,7 +52,7 @@ import com.fasterxml.jackson.databind.ObjectMapper {{#returnType}} @Suppress("UNCHECKED_CAST") {{/returnType}} - {{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}open suspend fun {{operationId}}({{#allParams}}{{{paramName}}}: {{{dataType}}}{{^required}}?{{/required}}{{^-last}}, {{/-last}}{{/allParams}}): HttpResponse<{{{returnType}}}{{^returnType}}Unit{{/returnType}}> { + {{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}open suspend fun {{operationId}}({{#allParams}}{{{paramName}}}: {{{dataType}}}{{#required}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/required}}{{^required}}?{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{^defaultValue}} = null{{/defaultValue}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}): HttpResponse<{{{returnType}}}{{^returnType}}Unit{{/returnType}}> { val localVariableAuthNames = listOf({{#authMethods}}"{{name}}"{{^-last}}, {{/-last}}{{/authMethods}}) diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/service.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/service.mustache index 73fb1332fda7..494c8202f0f8 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/service.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/service.mustache @@ -27,7 +27,7 @@ interface {{classname}}Service { {{/externalDocs}} * @see {{classname}}#{{operationId}} */ - {{#reactive}}{{^isArray}}suspend {{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{{paramName}}}: {{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}Flow<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{^-last}}, {{/-last}}{{/allParams}}): {{>returnTypes}} + {{#reactive}}{{^isArray}}suspend {{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{{paramName}}}: {{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}Flow<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{^required}}{{^defaultValue}} = null{{/defaultValue}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}): {{>returnTypes}} {{/operation}} } {{/operations}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/serviceImpl.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/serviceImpl.mustache index 0d11f745b29a..d4f5c5f86658 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/serviceImpl.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/serviceImpl.mustache @@ -10,7 +10,7 @@ import kotlinx.coroutines.flow.Flow class {{classname}}ServiceImpl : {{classname}}Service { {{#operation}} - override {{#reactive}}{{^isArray}}suspend {{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{paramName}}: {{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}Flow<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{^-last}}, {{/-last}}{{/allParams}}): {{>returnTypes}} { + override {{#reactive}}{{^isArray}}suspend {{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{paramName}}: {{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}Flow<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{^required}}{{^defaultValue}} = null{{/defaultValue}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}): {{>returnTypes}} { TODO("Implement me") } {{/operation}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/service.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/service.mustache index 0c524ab1ec6a..79b772197972 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/service.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/service.mustache @@ -29,7 +29,7 @@ interface {{classname}}Service { {{/externalDocs}} * @see {{classname}}#{{operationId}} */ - {{#reactive}}{{^isArray}}suspend {{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{{paramName}}}: {{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}Flow<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}ctx: Context): {{>returnTypes}} + {{#reactive}}{{^isArray}}suspend {{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{{paramName}}}: {{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}Flow<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{^required}}{{^defaultValue}} = null{{/defaultValue}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}ctx: Context): {{>returnTypes}} {{/operation}} } {{/operations}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/serviceImpl.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/serviceImpl.mustache index 7358a3492eab..64ad903b49ac 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/serviceImpl.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/serviceImpl.mustache @@ -11,7 +11,7 @@ import kotlinx.coroutines.flow.Flow class {{classname}}ServiceImpl : {{classname}}Service { {{#operation}} - override {{#reactive}}{{^isArray}}suspend {{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{paramName}}: {{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}Flow<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}ctx: Context): {{>returnTypes}} { + override {{#reactive}}{{^isArray}}suspend {{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{paramName}}: {{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}Flow<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{^required}}{{^defaultValue}} = null{{/defaultValue}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}ctx: Context): {{>returnTypes}} { TODO("Implement me") } {{/operation}} From 8d997798ee44aec97ea7ab4a75e7c9b1cd37d1c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Kozak?= Date: Tue, 3 Mar 2026 14:28:17 +0100 Subject: [PATCH 2/5] [kotlin] Add `= null` default for optional parameters in jvm-ktor templates and javalin serviceImpls Expanded test coverage for jvm-ktor optional parameters to verify `= null` defaults in generated code. Updated javalin5 and javalin6 serviceImpl templates to include correct default value assignments. --- .../libraries/javalin5/serviceImpl.mustache | 2 +- .../libraries/javalin6/serviceImpl.mustache | 2 +- .../kotlin/KotlinClientCodegenApiTest.java | 17 +++++++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/serviceImpl.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/serviceImpl.mustache index d4f5c5f86658..0d11f745b29a 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/serviceImpl.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/serviceImpl.mustache @@ -10,7 +10,7 @@ import kotlinx.coroutines.flow.Flow class {{classname}}ServiceImpl : {{classname}}Service { {{#operation}} - override {{#reactive}}{{^isArray}}suspend {{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{paramName}}: {{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}Flow<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{^required}}{{^defaultValue}} = null{{/defaultValue}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}): {{>returnTypes}} { + override {{#reactive}}{{^isArray}}suspend {{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{paramName}}: {{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}Flow<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{^-last}}, {{/-last}}{{/allParams}}): {{>returnTypes}} { TODO("Implement me") } {{/operation}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/serviceImpl.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/serviceImpl.mustache index 64ad903b49ac..7358a3492eab 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/serviceImpl.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/serviceImpl.mustache @@ -11,7 +11,7 @@ import kotlinx.coroutines.flow.Flow class {{classname}}ServiceImpl : {{classname}}Service { {{#operation}} - override {{#reactive}}{{^isArray}}suspend {{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{paramName}}: {{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}Flow<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{^required}}{{^defaultValue}} = null{{/defaultValue}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}ctx: Context): {{>returnTypes}} { + override {{#reactive}}{{^isArray}}suspend {{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{paramName}}: {{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}Flow<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}ctx: Context): {{>returnTypes}} { TODO("Implement me") } {{/operation}} diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinClientCodegenApiTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinClientCodegenApiTest.java index 69e1b3ecd2bd..538891a21241 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinClientCodegenApiTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinClientCodegenApiTest.java @@ -91,6 +91,23 @@ public void testUseResponseAsReturnType(Object useResponseAsReturnType, String e assertFileContainsLine(lines, "suspend fun deletePet(@Path(\"petId\") petId: kotlin.Long, @Header(\"api_key\") apiKey: kotlin.String? = null)" + expectedUnitResponse); } + @Test + public void testOptionalParamsHaveDefaultNullJvmKtor() throws IOException { + OpenAPI openAPI = readOpenAPI("3_0/kotlin/petstore.yaml"); + + KotlinClientCodegen codegen = createCodegen(ClientLibrary.JVM_KTOR); + + ClientOptInput input = createClientOptInput(openAPI, codegen); + + DefaultGenerator generator = new DefaultGenerator(); + enableOnlyApiGeneration(generator); + + List files = generator.opts(input).generate(); + File petApi = files.stream().filter(file -> file.getName().equals("PetApi.kt")).findAny().orElseThrow(); + + assertFileContains(petApi.toPath(), "apiKey: kotlin.String? = null"); + } + @Test public void testEnumDefaultForReferencedSchemaParameterJvmOkhttp4() throws IOException { OpenAPI openAPI = readOpenAPI("3_0/kotlin/enum-default-query.yaml"); From a0f8750498daee51da103e78510c4e07cf81ea1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Kozak?= Date: Tue, 3 Mar 2026 15:12:34 +0100 Subject: [PATCH 3/5] [kotlin] Fix nullable Flow types in javalin5 and javalin6 service templates --- .../resources/kotlin-server/libraries/javalin5/service.mustache | 2 +- .../resources/kotlin-server/libraries/javalin6/service.mustache | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/service.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/service.mustache index 494c8202f0f8..2517ed8d01bb 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/service.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/service.mustache @@ -27,7 +27,7 @@ interface {{classname}}Service { {{/externalDocs}} * @see {{classname}}#{{operationId}} */ - {{#reactive}}{{^isArray}}suspend {{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{{paramName}}}: {{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}Flow<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{^required}}{{^defaultValue}} = null{{/defaultValue}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}): {{>returnTypes}} + {{#reactive}}{{^isArray}}suspend {{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{{paramName}}}: {{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}Flow<{{{baseType}}}>{{^required}}{{^defaultValue}}?{{/defaultValue}}{{/required}}{{/isArray}}{{/reactive}}{{/isBodyParam}}{{^required}}{{^defaultValue}} = null{{/defaultValue}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}): {{>returnTypes}} {{/operation}} } {{/operations}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/service.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/service.mustache index 79b772197972..2cd2076f1039 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/service.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/service.mustache @@ -29,7 +29,7 @@ interface {{classname}}Service { {{/externalDocs}} * @see {{classname}}#{{operationId}} */ - {{#reactive}}{{^isArray}}suspend {{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{{paramName}}}: {{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}Flow<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{^required}}{{^defaultValue}} = null{{/defaultValue}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}ctx: Context): {{>returnTypes}} + {{#reactive}}{{^isArray}}suspend {{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{{paramName}}}: {{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}Flow<{{{baseType}}}>{{^required}}{{^defaultValue}}?{{/defaultValue}}{{/required}}{{/isArray}}{{/reactive}}{{/isBodyParam}}{{^required}}{{^defaultValue}} = null{{/defaultValue}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}ctx: Context): {{>returnTypes}} {{/operation}} } {{/operations}} From 79ed89c3883ebc765811c48132fdc86f2f1f6162 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Kozak?= Date: Thu, 5 Mar 2026 10:17:05 +0100 Subject: [PATCH 4/5] Update samples for kotlin jvm-ktor and javalin templates Co-Authored-By: Claude Opus 4.6 --- .../src/main/kotlin/org/openapitools/client/apis/FakeApi.kt | 2 +- .../src/main/kotlin/org/openapitools/client/apis/PetApi.kt | 6 +++--- .../src/main/kotlin/org/openapitools/client/apis/PetApi.kt | 6 +++--- .../src/main/kotlin/org/openapitools/client/apis/PetApi.kt | 6 +++--- .../kotlin/org/openapitools/server/apis/PetApiService.kt | 6 +++--- .../kotlin/org/openapitools/server/apis/PetApiService.kt | 6 +++--- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/samples/client/petstore/kotlin-jvm-ktor-gson/src/main/kotlin/org/openapitools/client/apis/FakeApi.kt b/samples/client/petstore/kotlin-jvm-ktor-gson/src/main/kotlin/org/openapitools/client/apis/FakeApi.kt index bc806e41e6d0..5c52462937f4 100644 --- a/samples/client/petstore/kotlin-jvm-ktor-gson/src/main/kotlin/org/openapitools/client/apis/FakeApi.kt +++ b/samples/client/petstore/kotlin-jvm-ktor-gson/src/main/kotlin/org/openapitools/client/apis/FakeApi.kt @@ -80,7 +80,7 @@ import java.text.DateFormat * @param status2 number type (optional) * @return void */ - open suspend fun updatePetWithFormNumber(petId: kotlin.Long, name: kotlin.String?, status: kotlin.Int?, status2: java.math.BigDecimal?): HttpResponse { + open suspend fun updatePetWithFormNumber(petId: kotlin.Long, name: kotlin.String? = null, status: kotlin.Int? = null, status2: java.math.BigDecimal? = null): HttpResponse { val localVariableAuthNames = listOf("petstore_auth") diff --git a/samples/client/petstore/kotlin-jvm-ktor-gson/src/main/kotlin/org/openapitools/client/apis/PetApi.kt b/samples/client/petstore/kotlin-jvm-ktor-gson/src/main/kotlin/org/openapitools/client/apis/PetApi.kt index 10be7a7bdf01..b3d9ee1b3130 100644 --- a/samples/client/petstore/kotlin-jvm-ktor-gson/src/main/kotlin/org/openapitools/client/apis/PetApi.kt +++ b/samples/client/petstore/kotlin-jvm-ktor-gson/src/main/kotlin/org/openapitools/client/apis/PetApi.kt @@ -80,7 +80,7 @@ import java.text.DateFormat * @param apiKey (optional) * @return void */ - open suspend fun deletePet(petId: kotlin.Long, apiKey: kotlin.String?): HttpResponse { + open suspend fun deletePet(petId: kotlin.Long, apiKey: kotlin.String? = null): HttpResponse { val localVariableAuthNames = listOf("petstore_auth") @@ -253,7 +253,7 @@ import java.text.DateFormat * @param status Updated status of the pet (optional) * @return void */ - open suspend fun updatePetWithForm(petId: kotlin.Long, name: kotlin.String?, status: kotlin.String?): HttpResponse { + open suspend fun updatePetWithForm(petId: kotlin.Long, name: kotlin.String? = null, status: kotlin.String? = null): HttpResponse { val localVariableAuthNames = listOf("petstore_auth") @@ -292,7 +292,7 @@ import java.text.DateFormat * @return ModelApiResponse */ @Suppress("UNCHECKED_CAST") - open suspend fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: io.ktor.client.request.forms.FormPart?): HttpResponse { + open suspend fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String? = null, file: io.ktor.client.request.forms.FormPart? = null): HttpResponse { val localVariableAuthNames = listOf("petstore_auth") diff --git a/samples/client/petstore/kotlin-jvm-ktor-jackson/src/main/kotlin/org/openapitools/client/apis/PetApi.kt b/samples/client/petstore/kotlin-jvm-ktor-jackson/src/main/kotlin/org/openapitools/client/apis/PetApi.kt index d81dff91aa77..125b891deefb 100644 --- a/samples/client/petstore/kotlin-jvm-ktor-jackson/src/main/kotlin/org/openapitools/client/apis/PetApi.kt +++ b/samples/client/petstore/kotlin-jvm-ktor-jackson/src/main/kotlin/org/openapitools/client/apis/PetApi.kt @@ -77,7 +77,7 @@ import com.fasterxml.jackson.databind.ObjectMapper * @param apiKey (optional) * @return void */ - open suspend fun deletePet(petId: kotlin.Long, apiKey: kotlin.String?): HttpResponse { + open suspend fun deletePet(petId: kotlin.Long, apiKey: kotlin.String? = null): HttpResponse { val localVariableAuthNames = listOf("petstore_auth") @@ -249,7 +249,7 @@ import com.fasterxml.jackson.databind.ObjectMapper * @param status Updated status of the pet (optional) * @return void */ - open suspend fun updatePetWithForm(petId: kotlin.Long, name: kotlin.String?, status: kotlin.String?): HttpResponse { + open suspend fun updatePetWithForm(petId: kotlin.Long, name: kotlin.String? = null, status: kotlin.String? = null): HttpResponse { val localVariableAuthNames = listOf("petstore_auth") @@ -288,7 +288,7 @@ import com.fasterxml.jackson.databind.ObjectMapper * @return ModelApiResponse */ @Suppress("UNCHECKED_CAST") - open suspend fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: io.ktor.client.request.forms.FormPart?): HttpResponse { + open suspend fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String? = null, file: io.ktor.client.request.forms.FormPart? = null): HttpResponse { val localVariableAuthNames = listOf("petstore_auth") diff --git a/samples/client/petstore/kotlin-jvm-ktor-kotlinx_serialization/src/main/kotlin/org/openapitools/client/apis/PetApi.kt b/samples/client/petstore/kotlin-jvm-ktor-kotlinx_serialization/src/main/kotlin/org/openapitools/client/apis/PetApi.kt index 9b1780135f25..60110a0ec8d4 100644 --- a/samples/client/petstore/kotlin-jvm-ktor-kotlinx_serialization/src/main/kotlin/org/openapitools/client/apis/PetApi.kt +++ b/samples/client/petstore/kotlin-jvm-ktor-kotlinx_serialization/src/main/kotlin/org/openapitools/client/apis/PetApi.kt @@ -75,7 +75,7 @@ import io.ktor.http.ParametersBuilder * @param apiKey (optional) * @return void */ - open suspend fun deletePet(petId: kotlin.Long, apiKey: kotlin.String?): HttpResponse { + open suspend fun deletePet(petId: kotlin.Long, apiKey: kotlin.String? = null): HttpResponse { val localVariableAuthNames = listOf("petstore_auth") @@ -248,7 +248,7 @@ import io.ktor.http.ParametersBuilder * @param status Updated status of the pet (optional) * @return void */ - open suspend fun updatePetWithForm(petId: kotlin.Long, name: kotlin.String?, status: kotlin.String?): HttpResponse { + open suspend fun updatePetWithForm(petId: kotlin.Long, name: kotlin.String? = null, status: kotlin.String? = null): HttpResponse { val localVariableAuthNames = listOf("petstore_auth") @@ -287,7 +287,7 @@ import io.ktor.http.ParametersBuilder * @return ModelApiResponse */ @Suppress("UNCHECKED_CAST") - open suspend fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: io.ktor.client.request.forms.FormPart?): HttpResponse { + open suspend fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String? = null, file: io.ktor.client.request.forms.FormPart? = null): HttpResponse { val localVariableAuthNames = listOf("petstore_auth") diff --git a/samples/server/petstore/kotlin-server/javalin-6/src/main/kotlin/org/openapitools/server/apis/PetApiService.kt b/samples/server/petstore/kotlin-server/javalin-6/src/main/kotlin/org/openapitools/server/apis/PetApiService.kt index 6c06f129bead..29534749b1ec 100644 --- a/samples/server/petstore/kotlin-server/javalin-6/src/main/kotlin/org/openapitools/server/apis/PetApiService.kt +++ b/samples/server/petstore/kotlin-server/javalin-6/src/main/kotlin/org/openapitools/server/apis/PetApiService.kt @@ -28,7 +28,7 @@ interface PetApiService { * @return Invalid pet value (status code 400) * @see PetApi#deletePet */ - fun deletePet(petId: kotlin.Long, apiKey: kotlin.String?, ctx: Context): Unit + fun deletePet(petId: kotlin.Long, apiKey: kotlin.String? = null, ctx: Context): Unit /** * GET /pet/findByStatus : Finds Pets by status @@ -95,7 +95,7 @@ interface PetApiService { * @return Invalid input (status code 405) * @see PetApi#updatePetWithForm */ - fun updatePetWithForm(petId: kotlin.Long, name: kotlin.String?, status: kotlin.String?, ctx: Context): Unit + fun updatePetWithForm(petId: kotlin.Long, name: kotlin.String? = null, status: kotlin.String? = null, ctx: Context): Unit /** * POST /pet/{petId}/uploadImage : uploads an image @@ -108,5 +108,5 @@ interface PetApiService { * @return successful operation (status code 200) * @see PetApi#uploadFile */ - fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: io.javalin.http.UploadedFile?, ctx: Context): ModelApiResponse + fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String? = null, file: io.javalin.http.UploadedFile? = null, ctx: Context): ModelApiResponse } diff --git a/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/PetApiService.kt b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/PetApiService.kt index 1783de4bca80..4a1cdb0a31e2 100644 --- a/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/PetApiService.kt +++ b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/PetApiService.kt @@ -25,7 +25,7 @@ interface PetApiService { * @return Invalid pet value (status code 400) * @see PetApi#deletePet */ - fun deletePet(petId: kotlin.Long, apiKey: kotlin.String?): Unit + fun deletePet(petId: kotlin.Long, apiKey: kotlin.String? = null): Unit /** * GET /pet/findByStatus : Finds Pets by status @@ -87,7 +87,7 @@ interface PetApiService { * @return Invalid input (status code 405) * @see PetApi#updatePetWithForm */ - fun updatePetWithForm(petId: kotlin.Long, name: kotlin.String?, status: kotlin.String?): Unit + fun updatePetWithForm(petId: kotlin.Long, name: kotlin.String? = null, status: kotlin.String? = null): Unit /** * POST /pet/{petId}/uploadImage : uploads an image @@ -99,5 +99,5 @@ interface PetApiService { * @return successful operation (status code 200) * @see PetApi#uploadFile */ - fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: io.javalin.http.UploadedFile?): ModelApiResponse + fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String? = null, file: io.javalin.http.UploadedFile? = null): ModelApiResponse } From 1c5412a1b995c52cc93cd926e54728dd5fe1cd6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Kozak?= Date: Mon, 9 Mar 2026 12:52:18 +0100 Subject: [PATCH 5/5] [kotlin] Simplify default value template logic per PR review Move defaultValue outside required-check since it always applies, simplify nullable/default patterns in jvm-ktor api.mustache and javalin5/javalin6 service.mustache templates. Co-Authored-By: Claude Opus 4.6 --- .../resources/kotlin-client/libraries/jvm-ktor/api.mustache | 2 +- .../resources/kotlin-server/libraries/javalin5/service.mustache | 2 +- .../resources/kotlin-server/libraries/javalin6/service.mustache | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-ktor/api.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-ktor/api.mustache index bff6f9ff53ea..8ef38bb9f2e4 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-ktor/api.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-ktor/api.mustache @@ -52,7 +52,7 @@ import com.fasterxml.jackson.databind.ObjectMapper {{#returnType}} @Suppress("UNCHECKED_CAST") {{/returnType}} - {{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}open suspend fun {{operationId}}({{#allParams}}{{{paramName}}}: {{{dataType}}}{{#required}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/required}}{{^required}}?{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{^defaultValue}} = null{{/defaultValue}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}): HttpResponse<{{{returnType}}}{{^returnType}}Unit{{/returnType}}> { + {{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}open suspend fun {{operationId}}({{#allParams}}{{{paramName}}}: {{{dataType}}}{{^required}}?{{/required}}{{#defaultValue}} = {{{.}}}{{/defaultValue}}{{^defaultValue}}{{^required}} = null{{/required}}{{/defaultValue}}{{^-last}}, {{/-last}}{{/allParams}}): HttpResponse<{{{returnType}}}{{^returnType}}Unit{{/returnType}}> { val localVariableAuthNames = listOf({{#authMethods}}"{{name}}"{{^-last}}, {{/-last}}{{/authMethods}}) diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/service.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/service.mustache index 2517ed8d01bb..52d19653b5bd 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/service.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/service.mustache @@ -27,7 +27,7 @@ interface {{classname}}Service { {{/externalDocs}} * @see {{classname}}#{{operationId}} */ - {{#reactive}}{{^isArray}}suspend {{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{{paramName}}}: {{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}Flow<{{{baseType}}}>{{^required}}{{^defaultValue}}?{{/defaultValue}}{{/required}}{{/isArray}}{{/reactive}}{{/isBodyParam}}{{^required}}{{^defaultValue}} = null{{/defaultValue}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}): {{>returnTypes}} + {{#reactive}}{{^isArray}}suspend {{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{{paramName}}}: {{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}Flow<{{{baseType}}}>{{^required}}{{^defaultValue}}?{{/defaultValue}}{{/required}}{{/isArray}}{{/reactive}}{{/isBodyParam}}{{#defaultValue}} = {{{.}}}{{/defaultValue}}{{^defaultValue}}{{^required}} = null{{/required}}{{/defaultValue}}{{^-last}}, {{/-last}}{{/allParams}}): {{>returnTypes}} {{/operation}} } {{/operations}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/service.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/service.mustache index 2cd2076f1039..bb510bcd3367 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/service.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/service.mustache @@ -29,7 +29,7 @@ interface {{classname}}Service { {{/externalDocs}} * @see {{classname}}#{{operationId}} */ - {{#reactive}}{{^isArray}}suspend {{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{{paramName}}}: {{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}Flow<{{{baseType}}}>{{^required}}{{^defaultValue}}?{{/defaultValue}}{{/required}}{{/isArray}}{{/reactive}}{{/isBodyParam}}{{^required}}{{^defaultValue}} = null{{/defaultValue}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}ctx: Context): {{>returnTypes}} + {{#reactive}}{{^isArray}}suspend {{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{{paramName}}}: {{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}Flow<{{{baseType}}}>{{^required}}{{^defaultValue}}?{{/defaultValue}}{{/required}}{{/isArray}}{{/reactive}}{{/isBodyParam}}{{#defaultValue}} = {{{.}}}{{/defaultValue}}{{^defaultValue}}{{^required}} = null{{/required}}{{/defaultValue}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}ctx: Context): {{>returnTypes}} {{/operation}} } {{/operations}}