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
20.85k stars 6.34k forks source link

[BUG] [DART] The constructors of generated nested class declarations do not instantiate fields. #4973

Open ka-zo opened 4 years ago

ka-zo commented 4 years ago

Bug Report Checklist

openapi-generator version

v4.2.2

OpenAPI declaration file content or url

My openapi.json specification:

{
    "openapi": "3.0.2",
    "info": {
        "title": "test",
        "version": "v1"
    },
    "paths": {
        "/api/v1/average/height/": {
            "post": {
                "tags": [
                    "height",
                    "average"
                ],
                "summary": "GetAverageHeight",
                "description": "Getaverageheightatthespecifiedage.",
                "operationId": "get_average_height_api_v1_average_height__post",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/Person"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "SuccessfulResponse",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PersonHeight"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "ValidationError",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "AgeValue": {
                "title": "AgeValue",
                "required": [
                    "unit",
                    "value"
                ],
                "type": "object",
                "properties": {
                    "unit": {
                        "title": "Unit",
                        "enum": [
                            "month"
                        ],
                        "type": "string"
                    },
                    "value": {
                        "title": "Value",
                        "maximum": 216.0,
                        "minimum": 0.0,
                        "type": "number",
                        "description": "Ageofperson."
                    }
                }
            },
            "HTTPValidationError": {
                "title": "HTTPValidationError",
                "type": "object",
                "properties": {
                    "detail": {
                        "title": "Detail",
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/ValidationError"
                        }
                    }
                }
            },
            "HeightValue": {
                "title": "HeightValue",
                "required": [
                    "unit",
                    "value"
                ],
                "type": "object",
                "properties": {
                    "unit": {
                        "title": "Unit",
                        "enum": [
                            "cm"
                        ],
                        "type": "string"
                    },
                    "value": {
                        "title": "Value",
                        "maximum": 300.0,
                        "minimum": 10.0,
                        "type": "number",
                        "description": "Valueoftheheight."
                    }
                }
            },
            "Person": {
                "title": "Person",
                "required": [
                    "age"
                ],
                "type": "object",
                "properties": {
                    "age": {
                        "$ref": "#/components/schemas/AgeValue"
                    }
                }
            },
            "PersonHeight": {
                "title": "PersonHeight",
                "required": [
                    "person",
                    "height"
                ],
                "type": "object",
                "properties": {
                    "person": {
                        "$ref": "#/components/schemas/Person"
                    },
                    "height": {
                        "$ref": "#/components/schemas/HeightValue"
                    }
                }
            },
            "ValidationError": {
                "title": "ValidationError",
                "required": [
                    "loc",
                    "msg",
                    "type"
                ],
                "type": "object",
                "properties": {
                    "loc": {
                        "title": "Location",
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                    "msg": {
                        "title": "Message",
                        "type": "string"
                    },
                    "type": {
                        "title": "ErrorType",
                        "type": "string"
                    }
                }
            }
        }
    },
    "servers": [
        {
            "url": "http://10.0.2.2:8000",
            "description": "Justatestserver."
        }
    ]
}

My flutterconfig-dart.json file:

{
    "browserClient": false,
    "useEnumExtension": true
}
Command line used for generation
java -jar .\openapi-generator-cli-4.2.2.jar generate -i .\openapi.json -g dart -o .\openapi-test -c flutterconfig-dart.json
Steps to reproduce

Just generate the code using the command line, and then open any model dart files, such as: \openapi-test\lib\model\person.dart

There you can see that the constructor of the Person class is Person(); So no instantiation of the field age takes place.

So in order to use the Person class you would need to do:

Person person = new Person();
person.age = new AgeValue(); // This would be totally unnecessary, with the fix I suggest below.

Imagine how big this problem is, if you wanted to instantiate a class with deeply nested field of other classes.

Suggest a fix

Extend all generated constructors to instantiate all fields.

auto-labeler[bot] commented 4 years ago

👍 Thanks for opening this issue! 🏷 I have applied any labels matching special text in your issue.

The team will review the labels and make any necessary changes.

ka-zo commented 3 years ago

An update to this issue: for versions 4.2.x and 4.3x of the OpenAPI Generator I have created my own class.mustache file including the following (not full) code snipet in the beginning of the class template:

class {{classname}} {
  {{#vars}}
    {{#description}}/* {{{description}}} */{{/description}}
    {{#isPrimitiveType}}
      {{{dataType}}} {{name}} = {{{defaultValue}}};
    {{/isPrimitiveType}}
    {{^isPrimitiveType}}
      {{{dataType}}} {{name}} = new {{{dataType}}}();
    {{/isPrimitiveType}}
    {{#allowableValues}}
    {{#min}} // range from {{min}} to {{max}}{{/min}}//{{^min}}enum {{name}}Enum { {{#values}} {{.}}, {{/values}} };{{/min}}{
    {{/allowableValues}}
    {{/vars}}
    {{classname}}();

The idea is that whenever the type of the parameter is complex, not a string, etc. but e.g. a class, then it gets instantiated. It was nicely working for me, for my OpenAPI json specification. Regarding the latest 5.0.0 beta releases, I do not expect changes in this regard. Instead of using my own class.mustache, my new solution for this is that my Dart code, that uses the Dart client code generated by the OpenAPI generator, needs to instantiate all classes that will be used as parameters in the generated classes. They need to be passed to the constructors of the generated classes, whenever I want to use them.