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.85k stars 6.59k forks source link

[BUG] [Kotlin] 5.2.0 generic request type cause issue Platform class kotlin.Unit requires explicit JsonAdapter to be registered if requestBody is not provided #10126

Open patiramyadav opened 3 years ago

patiramyadav commented 3 years ago

When using latest version 5.2.0. I have tested with 5.2.1-SNAPSHOT and has still this issue. This works with 5.1.1 version.

java.lang.IllegalArgumentException: Platform class kotlin.Unit requires explicit JsonAdapter to be registered
    at com.squareup.moshi.ClassJsonAdapter$1.create(ClassJsonAdapter.java:75)
    at com.squareup.moshi.Moshi.adapter(Moshi.java:145)
    at com.squareup.moshi.Moshi.adapter(Moshi.java:105)
    at com.squareup.moshi.Moshi.adapter(Moshi.java:79)

Spec:

openapi: 3.0.1
paths:
  /v1/abcs/{id}/cancel:
    patch:
      tags:
        - Abcs
      operationId: cancelAbc
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MockResponse'
    MockResponse:
      required:
        - response
      type: object
      properties:
        response:
          $ref: '#/components/schemas/Response'
 components:
   schemas:     
      Response:
            required:
              - confirmationId
            type: object
            properties:
              id:
                type: string
                format: uuid
              confirmationId:
                type: string

Note: no requestBody for patch.

Generated code:

    suspend fun cancelAbc(id: java.util.UUID) : MockResponse{
        val localVariableConfig = cancelAbcRequestConfig(id = id)

        val localVarResponse = request<Unit, MockResponse>(
            localVariableConfig
        )
       .....
}

data class MockResponse (
    @Json(name = "response")
    val response: Response
)

Here, the request type is Unit. while 5.1.1 generates only request<MockResponse> no request type.

Extra related dependencies:

    implementation("com.squareup.moshi:moshi-kotlin:1.12.0")
    implementation "com.squareup.okhttp3:okhttp:4.9.0"
patiramyadav commented 3 years ago

When I add requestBody it works and I see generated code as follows:

      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MockRequest'
        required: false

Then

    suspend fun cancelAbc(id: java.util.UUID) : MockResponse{
        val localVariableConfig = cancelAbcRequestConfig(id = id)

        val localVarResponse = request<Unit, MockResponse>(
            localVariableConfig
        )
       .....
}

Changed to

    suspend fun cancelAbc(id: java.util.UUID, mockRequest: MockRequest?) : MockResponse{
        val localVariableConfig = cancelAbcRequestConfig(id = id)

        val localVarResponse = request<MockRequest, MockResponse>(
            localVariableConfig
        )
       .....
}

The problem is Unit as request type when no explicit requestBody is added in specification of openAPI.

mikand13 commented 3 years ago

👍

patiramyadav commented 3 years ago

@krzema12 Can you please review this and let me know any suggestion? I am very beginner for openAPI generator.

krzema12 commented 3 years ago

@patiramyadav sorry, I have literally no experience with Moshi. I contributed to Kotlin Multiplatform template where I kinda know kotlinx.serialization used for JSON serialization.

Anyway, my high-level suggestions about the bugfixing process in OpenAPI generator would be to:

  1. Prepare a reviewable PR out of your comments. It's pretty hard for me to infer which changes exactly you mean, how they influence other pieces of generated code, and so on. With a PR, it's also possible for a reviewer to check out your repo and branch locally and play with it.
  2. In the PR as reviewers, include contributors that recently touched the given template. I'm not a good choice since I don't want to pretend I know Moshi and give functional hints :)
  3. Check why this regression got into the release. I see there are some tests around kotlin-moshi-codegen here: https://github.com/OpenAPITools/openapi-generator/blob/master/.github/workflows/samples-kotlin.yaml#L32 . Best if this bugfix was done in a TDD manner (first, add a test that would fail without this bugfix, and then make the test pass with a proper bugfix).
mark-zhou commented 3 years ago

I'm also affected by this bug, which started around April. I noticed it can be "fixed" in the generated code by adding a "content == null" branch in the ApiClient class like this:

protected inline fun <reified T> requestBody(content: T, mediaType: String = JsonMediaType): RequestBody =
    when {
        content is File -> content.asRequestBody(mediaType.toMediaTypeOrNull())
        content == null -> ByteArray(0).toRequestBody()