OpenAPITools / OpenAPITools/openapi-generator

[REQ] Interpret anyOf with a single primitive subtype as alias to that primitive type

Open
#13,784 0 comments 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Enhancement: Feature
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

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

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.