Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG][Kotlin][retrofit2] Enums in request body represented as String parameters, default value is wrong, resulting code does not compile #20020

Open
4 of 6 tasks
lukas1 opened this issue Nov 4, 2024 · 1 comment

Comments

@lukas1
Copy link

lukas1 commented Nov 4, 2024

Bug Report Checklist

  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator (example)?
  • Have you tested with the latest master to confirm the issue still exists?
  • Have you searched for related issues/PRs?
  • What's the actual output vs expected output?
  • [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

There's an issue generating models for API spec that contains enums in request body for Kotlin and Retrofit 2. Enums are generated, but the request method then uses Strings as parameters. If a default value is provided, the result is even code that doesn't compile at all, because the default value doesn't have quotation marks for String.

openapi-generator version

7.9.0

OpenAPI declaration file content or url
openapi: 3.0.3
info:
  title: enum_api
  version: '1.0'
  description: |-
    This specification demonstrates an issue in Kotlin code generator for Retrofit
servers:
  - description: Server
    url: 'https://test.com'
paths:
  /test:
    post:
      summary: Test
      responses:
        '200':
          description: Test
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Response'
              examples: {}
      description: Test
      requestBody:
        content:
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/Request'
        description: Test
      security: []
components:
  schemas:
    Response:
      title: Response
      type: object
      properties:
        property:
          type: string
          example: eyJhbGciOiJIUzI1NiIs...
          description: Test
    Request:
      title: Request
      type: object
      properties:
        enum_prop_type:
          type: string
          enum:
            - 'test1'
            - 'test2'
          example: 'test1'
          default: 'test1'
          description: Test
      required:
        - enum_prop_type
Generation Details

Setup of the gradle task that fails to generate proper Kotlin code:

task openApiGenerateTestApi(type: GenerateTask) {
    globalProperties = [
            supportingFiles: "",
            apis           : "",
            models         : "",
    ]
    inputSpec = "$rootDir/app/api-specs/openapi_enum_service.yml"
    generatorName = "kotlin"
    outputDir = "$rootDir/app"
    modelPackage = "com.example.openapienumbug.openapi.entities"
    apiPackage = "com.example.openapienumbug.openapi.api"
    modelNameSuffix = "Entity"
    additionalProperties = [
            useCoroutines: "true",
            library      : "jvm-retrofit2",
            sourceFolder : "src/main/java",
            "enumPropertyNaming": "UPPERCASE"
    ]
    ignoreFileOverride = "$rootDir/.openapi-generator-ignore"
}
Steps to reproduce

Run the openApiGenerateTestApi task in the demo app provided here:

OpenApiEnumBug.zip

Observe the generated Kotlin code of the file DefaultApi.kt

Here's the generated file:

package com.example.openapienumbug.openapi.api

import org.openapitools.client.infrastructure.CollectionFormats.*
import retrofit2.http.*
import retrofit2.Response
import okhttp3.RequestBody
import com.squareup.moshi.Json

import com.example.openapienumbug.openapi.entities.ResponseEntity

interface DefaultApi {

    /**
    * enum for parameter enumPropType
    */
    enum class EnumPropTypeTestPost(val value: kotlin.String) {
        @Json(name = "test1") TEST1("test1"),
        @Json(name = "test2") TEST2("test2")
    }

    /**
     * Test
     * Test
     * Responses:
     *  - 200: Test
     *
     * @param enumPropType Test (default to test1)
     * @return [ResponseEntity]
     */
    @FormUrlEncoded
    @POST("test")
    suspend fun testPost(@Field("enum_prop_type") enumPropType: kotlin.String = test1): Response<ResponseEntity>

}

Notice how the EnumPropTypeTestPost is not used inside the testPost method, for the enumPropType. A String is used as the type. On top of that, the default value test1 is not wrapped by quotation marks for a String parameter.

This would be the expected result:

package com.example.openapienumbug.openapi.api

import org.openapitools.client.infrastructure.CollectionFormats.*
import retrofit2.http.*
import retrofit2.Response
import okhttp3.RequestBody
import com.squareup.moshi.Json

import com.example.openapienumbug.openapi.entities.ResponseEntity

interface DefaultApi {

    /**
    * enum for parameter enumPropType
    */
    enum class EnumPropTypeTestPost(val value: kotlin.String) {
        @Json(name = "test1") TEST1("test1"),
        @Json(name = "test2") TEST2("test2")
    }

    /**
     * Test
     * Test
     * Responses:
     *  - 200: Test
     *
     * @param enumPropType Test (default to test1)
     * @return [ResponseEntity]
     */
    @FormUrlEncoded
    @POST("test")
    suspend fun testPost(@Field("enum_prop_type") enumPropType: EnumPropTypeTestPost = EnumPropTypeTestPost.TEST1): Response<ResponseEntity>

}
Related issues/PRs

I did not find anything related

Suggest a fix

No suggestion on my side

@lukas1
Copy link
Author

lukas1 commented Nov 6, 2024

The fact that Strings and not Enums are used in the parameters may not necessarily be a bug. Retrofit does not support enums for @FormUrlEncoded properly, one would need to provide also some converter for them. Maybe it was intentional for @FormUrlEncoded to use strings.

But the fact that when default value is provided the resulting code does not compile is a clear bug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant