[BUG] [Kotlin] DTOs for components of different components are conflated if they have the same members
Bug Report Checklist
- [ X ] Have you provided a full/minimal spec to reproduce the issue?
- [ X ] Have you validated the input using an OpenAPI validator (example)?
- [ ] Have you tested with the latest master to confirm the issue still exists?
- [ X ] Have you searched for related issues/PRs?
- [ X ] What's the actual output vs expected output?
- [ ] [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description
In my minimal repro, I have two types of data. The issue component has a user with fields id and name. The item component also has a user with fields id and name. The generated Kotlin code consists of an ItemDto, an IssueDto, and an ItemUserDto.
The problem is the following: the IssueDto references the ItemUserDto. I do not expect that:
- Although these
userobjects by coincidence have the same members at the moment, these are entirely different , and are expected to have different members in the future, as the API evolves. If I had wanted to have aUserDtoas a concept which is shared by the two components, I would have declared theuserobject as a global component. - also, the name
ItemUserDtois misleading, since the DTO is used in the context of an issue.
openapi-generator version
I tried it out with versions 6.5.0 and 7.5.0. I was not able yet to verify that it still occurs with 7.6.0, since I had trouble updating to 7.6.0.
OpenAPI declaration file content or url
openapi: 3.0.0
info:
title: Test API
version: 1.0.0
components:
schemas:
Item:
type: object
properties:
id:
type: string
format: uuid
description: Unique identifier for the item
example: "123e4567-e89b-12d3-a456-426614174001"
user:
type: object
properties:
id:
type: string
format: uuid
description: Unique identifier for the user
example: "123e4567-e89b-12d3-a456-426614174000"
name:
type: string
description: Name of the user
example: "John Doe"
required:
- id
- name
required:
- id
- user
Issue:
type: object
properties:
id:
type: string
format: uuid
description: Unique identifier for the issue
example: "987e6543-b21a-43c2-b789-876543210000"
user:
type: object
properties:
id:
type: string
format: uuid
description: Unique identifier for the user
example: "123e4567-e89b-12d3-a456-426614174000"
name:
type: string
description: Name of the user
example: "John Doe"
required:
- id
- name
required:
- id
- user
paths:
/items:
get:
summary: Get items
responses:
'200':
description: A list of items
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Item'
/issues:
get:
summary: Get issues
responses:
'200':
description: A list of issues
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Issue'
Generation Details
The following is the relevant part of our build.gradle.kts:
inputSpec.set("$rootDir/src/main/resources/static/openapi.yaml")
outputDir.set(openApiOutputDirPath.get().toString())
packageName.set(rootProject.name)
invokerPackage.set("${rootProject.name}.security")
apiPackage.set("${rootProject.name}.api")
modelPackage.set("${rootProject.name}.model")
modelNameSuffix.set("Dto")
generatorName.set("kotlin-spring")
configOptions.set(
mapOf(
"useSpringBoot3" to "true",
"delegatePattern" to "true",
"interfaceOnly" to "true",
"dateLibrary" to "java8",
"useTags" to "true",
"enumPropertyNaming" to "UPPERCASE"
)
)
}
Steps to reproduce
Invoke the gradle build task described above
Related issues/PRs
None found.
Suggest a fix
I will refer to the above example for clarity. I suggest to generate not only an ItemDto, an IssueDto, and an ItemUserDto, but also an IssueUserDto. The IssueUserDto should be referenced by the IssueDto.
I understand that changing the generated types as a default behavior would incur a breaking change; we can introduce a new configuration option dontReuseDtoTypes = true or similar to enable the new behavior suggested above.