OpenAPITools / OpenAPITools/openapi-generator
[REQ] Interpret anyOf with a single primitive subtype as alias to that primitive type
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 26.8k
- Forks
- 7.7k
- PR merge metrics
- PR metrics pending
Description
Problem
I am confronted with a third party openapi definition that uses a lot of "anyOf"-types which have only one subtype. Supposedly this is to add context specific descriptions to parameters like in the following example.
openapi: 3.0.2
components:
schemas:
Id:
description: An id.
type: string
minLength: 16
maxLength: 128
example: 9d1aaa59-80b7-4c11-922c-8a2b4rrr6b2d
EntityWithId:
description: Entity with id
type: object
properties:
id:
# Here we can't add a description to this property
$ref: '#/components/schemas/Id'
# This should be equivalent, and we can add a description.
idReference:
description: id, populated only when the third party system provided it
anyOf:
- $ref: '#/components/schemas/Id'
The problem is, that this generates a very complicated model. That is unnecessary, since these types work as aliases to "string". Furthermore, the java webclient library doesn't implement anyOf correctly, yet.
By the way: In the original api, this kind of structure was not always just one level deep. There were references to references to references as well...
Solution
I would like these types to be regarded as aliases. That means, that parameters are no longer typed EntityWithIdIdReference but simply String instead .
I did create a fix by adding some code to DefaultCodegen.getAllAliases(...) to change the behaviour. Should I create a pull request for that and/or do you have a better place in mind? I could try to add a configuration to switch that behaviour on/off plus alternative paths for oneOf (etc.), if you are interested. It's just a proof of concept for now but it seems to work for us.
boolean foundNewAlias;
do {
foundNewAlias = false;
for (Map.Entry<String, Schema> entry : schemas.entrySet()) {
if (aliases.containsKey(entry.getKey())) {
continue;
}
Schema schema = entry.getValue();
List<Schema> anyOf = schema.getAnyOf();
if (anyOf != null && anyOf.size() == 1) {
String aliasType = ModelUtils.getSimpleRef(anyOf.get(0).get$ref());
if (aliases.containsKey(aliasType)) {
aliases.put(entry.getKey(), aliases.get(aliasType));
foundNewAlias = true;
}
}
}
} while (foundNewAlias);
Describe alternatives you've considered
I tried using a different library (java native) to get a correct anyOf implementation, but that one resulted in different bugs.
Also, any solution inside one generator or template would not fix the "more complicated than necessary"-problem for other languages.
Problems with the proposed solution
I suppose that implementation won't add correct validation constraints to these variables. Also, the additional documentation in the openapi file will be lost in the java code. For us, that would be okay. But maybe there is a better way?
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in DefaultCodegen.getAllAliases(...) and inspect how schemas containing a single-item anyOf are resolved, including nested references. Determine the expected alias behavior and validation or documentation trade-offs, then add coverage using the repository's existing codegen tests. Done means the behavior is consistently defined and verified without relying on a generator-specific template change.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- api, tooling
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100