OpenAPITools / openapi-generator

OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec (v2, v3)
https://openapi-generator.tech
Apache License 2.0
21.35k stars 6.46k forks source link

[BUG] [Kotlin] entries property in json spec generates wrong propertyEntries in the Kotlin class #13208

Closed AlexTrotsenko closed 1 year ago

AlexTrotsenko commented 2 years ago

I have following definition of the DTO in the open-api spec:

{
    "openapi": "3.0.0",
    "info": {
        "title": "Swagger AppInterface Documentation",
        "description": "[Scheme]",
        "version": "Release 2.0"
    },
    "components": {
        "schemas": {
            "OrderOverviewResponse": {
                "type": "object",
                "properties": {
                    "entries": {
                        "type": "array",
                        "description": "Contains the history entries",
                        "items": {
                            "$ref": "#/components/schemas/OrderOverviewEntryResponse"
                        }
                    },
                    "groups": {
                        "type": "array",
                        "description": "Contains the groups, initiated by the current user",
                        "items": {
                            "$ref": "#/components/schemas/OrderOverviewGroupResponse"
                        }
                    },
                    "serverUpdateTime": {
                        "type": "string",
                        "format": "date-time",
                        "description": "The server time as string in the format yyyy-MM-dd'T'HH:mm:ss'Z' (ISO-8601) in Zulu time zone (UTC)"
                    },
                    "pageToken": {
                        "type": "string",
                        "description": "A new page token that references the start of the next page.\nThis page token replaces the page token at the client, that may had been given as a request parameter.\nWhen the client calls this method the next time, this new page token may be passed.\nThis field is in the response undefined, if and only if no next page is available."
                    }
                },
                "required": [
                    "entries",
                    "serverUpdateTime"
                ]
            },
....

In the output all the properties are generated with the same name as in the openapi spec, but entries become propertyEntries for unknown reason.


@file:Suppress(
    "ArrayInDataClass",
    "EnumEntryName",
    "RemoveRedundantQualifierName",
    "UnusedImport"
)

package ch.twint.scheme.sdk.retrofit.model

import ch.twint.scheme.sdk.retrofit.model.OrderOverviewEntryResponseInfo
import ch.twint.scheme.sdk.retrofit.model.OrderOverviewGroupResponseInfo

import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass

/**
 * 
 *
 * @param propertyEntries Contains the history entries
 * @param serverUpdateTime The server time as string in the format yyyy-MM-dd'T'HH:mm:ss'Z' (ISO-8601) in Zulu time zone (UTC)
 * @param groups Contains the groups, initiated by the current user
 * @param pageToken A new page token that references the start of the next page. This page token replaces the page token at the client, that may had been given as a request parameter. When the client calls this method the next time, this new page token may be passed. This field is in the response undefined, if and only if no next page is available.
 */
@JsonClass(generateAdapter = true)
data class OrderOverviewResponseInfo (

    /* Contains the history entries */
    @Json(name = "entries")
    val propertyEntries: kotlin.collections.List<OrderOverviewEntryResponseInfo>,

    /* The server time as string in the format yyyy-MM-dd'T'HH:mm:ss'Z' (ISO-8601) in Zulu time zone (UTC) */
    @Json(name = "serverUpdateTime")
    val serverUpdateTime: java.time.OffsetDateTime,

    /* Contains the groups, initiated by the current user */
    @Json(name = "groups")
    val groups: kotlin.collections.List<OrderOverviewGroupResponseInfo>? = null,

    /* A new page token that references the start of the next page. This page token replaces the page token at the client, that may had been given as a request parameter. When the client calls this method the next time, this new page token may be passed. This field is in the response undefined, if and only if no next page is available. */
    @Json(name = "pageToken")
    val pageToken: kotlin.String? = null

)

Here is my set-up:

buildscript {
    ext.kotlin_version = '1.5.10'
    ext.retrofitVersion = '2.9.0'

    repositories {
        maven { url "https://repo1.maven.org/maven2" }
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

        classpath "org.openapitools:openapi-generator-gradle-plugin:5.4.0"
    }
}

plugins {
    id "maven-publish"
}

apply plugin: 'org.openapi.generator'
apply plugin: 'kotlin'
apply plugin: 'kotlin-kapt'

...

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
    implementation "com.squareup.moshi:moshi-kotlin:1.12.0"
    implementation "com.squareup.moshi:moshi-adapters:1.12.0"
    kapt "com.squareup.moshi:moshi-kotlin-codegen:1.12.0"
    implementation "com.squareup.okhttp3:logging-interceptor:4.9.1"
    implementation "com.squareup.retrofit2:retrofit:$retrofitVersion"
    implementation "com.squareup.retrofit2:converter-moshi:$retrofitVersion"
    implementation "com.squareup.retrofit2:converter-scalars:$retrofitVersion"
    testImplementation "io.kotlintest:kotlintest-runner-junit5:3.4.2"
}
openApiGenerate {
    generatorName = "kotlin"
    inputSpec = "$projectDir/../../../../AppInterface.json"
    outputDir = "$buildDir/generated/openapi"
    groupId = "$project.group"
    id = "$project.name"
    version = "$project.version"
    packageName = "$project.group" + ".retrofit"
    apiPackage = packageName.get() + ".api"
    modelPackage = packageName.get() + ".model"
    modelNameSuffix = "Info"
    configOptions = [
            apiSuffix : "NetworkService",
            java8               : "true",
            dateLibrary         : "java8",
            library             : "jvm-retrofit2",
            serializationLibrary : "moshi",
            moshiCodeGen: "true",
            useCoroutines: "true",
            enumPropertyNaming: "original",
            sortModelPropertiesByRequiredFlag: "true",
            sortParamsByRequiredFlag: "true",
            modelMutable: "false"
    ]
}
MuneebBaderoen commented 1 year ago

I've noticed this behaviour with a values attribute as well, which behaves similarly producing a propertyValues attribute in the generated Kotlin class. I'm not sure if there are other reserved words this may be affected by, but have seen this behaviour with both entries and values

wli-chwy commented 1 year ago

bump this bug. I am trying to upgrade from 5.2.0 to 5.4.0. And I see this issue. And I cannot make the upgrade until this issue is resolved.

wing328 commented 1 year ago

I could repeat the "issue" (property name escaped with property prefix) with the latest master.

Recently we've added a new feature called nameMappings to let users have complete control of the property name, e.g.

 java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g kotlin -i modules/openapi-generator/src/test/resources/3_0/petstore.yaml -o /tmp/kotlin/ --name-mappings entries=theEntries

This example maps entries to theEntries to showcase the feature. You can map it back to just entries with --name-mappings entries=entries

wing328 commented 1 year ago

Closed via https://github.com/OpenAPITools/openapi-generator/pull/16193