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.69k stars 6.55k forks source link

[BUG][JAVA] Client generates generic Object for items within array #11145

Open toby-murray-snow-software opened 2 years ago

toby-murray-snow-software commented 2 years ago

Bug Report Checklist

Description

Expected: DetailsObject would generate a model object, e.g. List<DetailsObject> or similar Actual: The generated function returns a generic List<Object> (public List<Object> bugReproductionGet() throws ApiException {)

openapi-generator version

5.3.0 and 5.3.1, but it seems like it might have regressed as early as 3.3.4 and been reproducible since then? Tested with master@ebc1d7bd

OpenAPI declaration file content or url
swagger: '2.0'
info:
  version: '3'
  title: API
host: 'localhost:8443'
basePath: /rest/v3
schemes:
  - https
consumes:
  - application/json
produces:
  - application/json

paths:
  /bug-reproduction:
    get:
      responses:
        '200':
          description: Success
          schema:
            $ref: '#/definitions/DetailsObject'

definitions:
  DetailsObject:
    type: array
    items:
      type: object
      properties:
        property_name:
          type: string
Generation Details

java -jar openapi-generator-cli-5.3.0.jar generate -i openapi-bug.yaml -g java

Steps to reproduce

Use the generation details and the provided YAML file

Related issues/PRs

I'm not sure, but https://github.com/OpenAPITools/openapi-generator/issues/108 looks similar

Suggest a fix
toby-murray-snow-software commented 2 years ago

Hmm, looking at the generator output it indicates:

...
[java] [main] INFO  o.o.codegen.DefaultGenerator - Model DetailsObject not generated since it's an alias to array (without property) and `generateAliasAsModel` is set to false (default)
...

Adding "generateAliasAsModel": "true" to my generator config seems to change this, but it's suspicious that it's required. Specifically I'm not sure what "an alias to array (without property)" is trying to indicate, as this is not just a generic array of objects.

mima0815 commented 2 years ago

The generated code with "generateAliasAsModel": "true" is creating the desired model object, but the object is still only a generic Object and not an Object with the properties defined how they are set under the properties entry:

DefaultApi.java:

  public DetailsObjectResponse bugReproductionGet() throws ApiException {
    return bugReproductionGetWithHttpInfo().getData();
  }

DetailsObjectResponse.java:

public class DetailsObjectResponse extends java.util.ArrayList<Object> implements Serializable {
  private static final long serialVersionUID = 1L;

  public DetailsObjectResponse() { 
  }

   //...

}

When moving the inner object under items to an $ref it is creating the right object structure: DetailsObjectResponse.java:

public class DetailsObjectResponse extends java.util.ArrayList<DetailsObjectEntry> implements Serializable {
  private static final long serialVersionUID = 1L;

  public DetailsObjectResponse() { 
  }

   //...

}

DetailsObjectEntry.java

public class DetailsObjectEntry implements Serializable {
  private static final long serialVersionUID = 1L;

  public static final String JSON_PROPERTY_TESTSTRINGREQUSET = "teststringrequset";
  private String teststringrequset;

  public DetailsObjectEntry() { 
  }

  //...

}

Same issue when using that as an request object in an post request.

Here my slightly modified spec file:

openapi: 3.0.0
info:
  version: '3'
  title: API
paths:
  /bug-reproduction:
    get:
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DetailsObjectResponse'

  /bug-reproduction-post:
    post:
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DetailsObjectRequest'

      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DetailsObjectResponse'

components:
  schemas:
    DetailsObjectResponse:
      type: array
      items:
        $ref: '#/components/schemas/DetailsObjectEntry'

    DetailsObjectRequest:
      type: array
      items:
        $ref: '#/components/schemas/DetailsObjectEntry'

    DetailsObjectEntry:
      type: object
      properties:
        teststringrequset:
          type: string
mima0815 commented 2 years ago

This issue occurs in charp and python too!