OpenAPITools / OpenAPITools/openapi-generator

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

Open
#4,973 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Client: Dart Issue: Bug
Dominant language
Java
Stars
26.8k
Forks
7.7k
PR merge metrics
PR metrics pending

Description

Bug Report Checklist
  • Have you provided a full/minimal spec to reproduce the issue? yes
  • Have you validated the input using an OpenAPI validator (example)? yes
  • What's the version of OpenAPI Generator used? v4.2.2
  • Have you search for related issues/PRs? yes
  • What's the actual output vs expected output? I expect classes in the generated model directory to have a non-empty constructor that also instantiates fields of the class. Some generated classes are embedded into other generated classes as fields. When such a class is instantiated, those fields of this class, that have a type of other generated classes do not get automatically instantiated. The consequence is that, when you want to use such a class, then you need to instantiate not just the class itself but also MANUALLY all its fields that do not get automatically instantiated. It's even worse, when such an object in a field has also fields,that need to be instantiated. I expect all generated classes to have a non-empty constructor, that automatically instantiates all fields that have a type of a generated class.
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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the issue with the provided OpenAPI specification, flutterconfig-dart.json, and generator command, then inspect openapi-test/lib/model/person.dart. Confirm that Person() leaves its age field uninstantiated, including the nested model relationships shown in the specification. Done means generated Dart constructors instantiate fields whose types are generated classes.

Written by the indexing model from the issue text.

Assessment

Tech stack
dart
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.