swagger-api / swagger-codegen

swagger-codegen contains a template-driven engine to generate documentation, API clients and server stubs in different languages by parsing your OpenAPI / Swagger definition.
http://swagger.io
Apache License 2.0
16.89k stars 6.03k forks source link

[Kotlin] Wrong array of objects code generation #9263

Open Yurdaaaaa opened 5 years ago

Yurdaaaaa commented 5 years ago
Description

Kotlin class generation is broken for specific .yaml shown bellow, but works correctly for Swift4. An arrayOf is not object at all and does not exists.

Swagger-codegen version

2.4.2

Swagger declaration file content or url
"swagger": "2.0"
Activities:
    type: array
    items:
      $ref: '#/definitions/ActivityItem'

ActivityItem:
    type: object
    required:
      - date
      - water
      - rest
      - food
    properties:
      date:
        type: string
        format: date-time
      water:
        type: number
      rest:
        type: number
      activity:
        type: number
      food:
        type: number
Generates this corrupt kotlin file
import io.swagger.client.models.ActivityItem
import io.swagger.client.models.arrayOf

/**
 * 
 */
data class Activities () {}
Swift4 same file correct generation
import Foundation

public typealias Activities = [ActivityItem]
Command line used for kotlin generation

swagger-codegen generate -l kotlin -i swagger.api.yaml -c swagger-codegen.config.json -o my_directory

Command line used for swift4 generation

swagger-codegen generate -l swift4 -i swagger.api.yaml -c swagger-codegen.config.json -o my_directory

Suggest a fix/enhancement

your parser is missing test for array of objects but i am not quite sure if it should look like this typealias also for kotlin typealias Activities = Array<ActivityItem>

mattinger commented 5 years ago

I'm also running into this issue. it seems any api response with an array as the top level element will have this issue.

Yurdaaaaa commented 5 years ago

@mattinger try this https://github.com/OpenAPITools/openapi-generator/pull/2375 or the latest master. One of the contributors contacted me and gave me few tips. This commit should propably have less problems than this codegen. Give it a try.

aaronlzxian commented 5 years ago

Which solves this problem, can you help?

mattinger commented 5 years ago

I pulled master and ran against that code 6 days ago (when i made the comment). I still got the same results. There are no commits since then which would be related to this issue.

mattinger commented 5 years ago

I made sure to update today as well, and I get the same result.

HugoMario commented 5 years ago

hey @mattinger, i'm not so familiar with kotlin but if you give me the expected output i can add a PR for fixing

mattinger commented 5 years ago

So for something like this:

  FeatureAvailability:
    type: array
    items:
      type: object
      properties:
        featureId:
          type: string
      required:
        - featureId

I'd expect something like this. I'm not sure how you'd work the naming though. I know that right now it puts "Inner" for the actual type that's going inside the array. I think it would be nice though if you could specifically name that type yourself by having a "name" property as a subproperty of the "items" tag.

typealias FeatureAvailability = Array<FeatureAvailabilityInner>
data class FeatureAvailabilityInner(val featureId: String)
aaronlzxian commented 5 years ago

continue following

aaronlzxian commented 5 years ago

solved this problem,find AbstractKotlinCodegen class file and modify addParentContainer function

private void addParentContainer(CodegenModel m, String name, Property property) {
        final CodegenProperty tmp = fromProperty(name, property);
        addImport(m, tmp.complexType);
        m.parent = toInstantiationType(property);
        final String containerType = tmp.containerType;
        final String instantiationType = instantiationTypes.get(containerType);
        if (instantiationType != null) {
            addImport(m, typeMapping.get("array"));
        }

        addVars(m,new HashMap<String, Property>(){{put(m.arrayModelType.toLowerCase(), property)}}, null, null)
    }
HugoMario commented 5 years ago

hey @aaronlzxian can you propose a PR based on solution you found?

nomisRev commented 5 years ago

Is there any other solution than proposed by @aaronlzxian?

I am using a custom KotlinClientCodegen, so I do not have access to the private method of DefaultCodegen.

This is based on this blog to walk around the incorrect nameInCamelCase values. Additionally I also add @Parcelize support to the data classes.

If I can fix this then I'd like to also add support for Helios Json library, and I could open a PR if there is interest in it.

For future reference: solved this by moving to OpenApi generator with the gradle plugin.

HugoMario commented 5 years ago

Hey @nomisRev, sorry for delay response. please go ahead with your propose and i can help you to get your changes merge.

4brunu commented 4 years ago

Having support for @Parcelize would be a great addition. This PR https://github.com/swagger-api/swagger-codegen/pull/8815 started it, but was abandoned.

pablisco commented 4 years ago

This is still a problem, is there a plan for this?