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
21.8k stars 6.58k forks source link

[BUG] 3.1.0 specs generate separate nested classes for shared enum types #17026

Open shorn opened 12 months ago

shorn commented 12 months ago
Description

OpenAPI 3.1.0 generates separate nested classes for shared enum types when the enum is defined in the global schema via a $ref.

The example project I've linked shows that a shared class is generated (Fruit) if the enum is not defined via a $ref, but generates nested enum classes if the enum is defined via a $ref (Vegetable).

The difference can be seen here in the definitions of the /generateFruitPallet and /generateVegetablePallet endpoints: https://github.com/shorn/openapi-fruitbat/blob/main/shared-enum-3.1/src/main/openapi/shared-enum.yaml

The only structural difference between those two endpoints is defining the enum via a $ref.

You can also see in this project that if the 3.0.3 spec is used, shared enum classes are generate regardless of whether the enum is defined via a $ref.

openapi-generator version

7.0.1 As per https://github.com/shorn/openapi-fruitbat/blob/4cd5a6125d8f2a5039d4fa3fd04ac7936eef04f6/shared-enum-3.1/build.gradle#L15

The example project shows that the enum class are correctly generated when using openapi verison 3.0.3 (but still same generator version 7.0.1)

OpenAPI declaration file content or url

OpenApi 3.1.0: https://github.com/shorn/openapi-fruitbat/blob/main/shared-enum-3.1/src/main/openapi/shared-enum.yaml OpenAPI 3.0.3: https://github.com/shorn/openapi-fruitbat/blob/main/shared-enum-3.0/src/main/openapi/shared-enum.yaml

Generation Details

Example github project: https://github.com/shorn/openapi-fruitbat

Steps to reproduce

Execute the :shared-enum-3.0:generateSpringServerInterface and :shared-enum-3.0:generateSpringServerInterface.

Then inspect the generated java code in each project's build/generated/spring directory. You will see that the 3.0.3 spec generates a shared class for the Vegetable type. But the 3.1.0 spec generates nested enums that are not assignment compatible.

You can also see the problem is present with other generator types by executing the generateTypescriptClient tasks.

Related issues/PRs

None that I could find.

Suggest a fix

I don't see how; but if it is decided that this behavior is "working as intended" - consider adding explicit documentation of that because it's going to cause people a lot of issues (especially for Java projects).

wing328 commented 7 months ago

did a test with latest master and the output compiles without issues

can you please give it another try with the latest master?

snapshot version available in the readme.

shorn commented 7 months ago

I use docker to run openapi (because of issues with $ref relative references on Windows). Is there a dockerhub tag that corresponds to master?

I tried with latest and it grabbed version:

> Task :shared-enum-3.1:printOpenApiVersion
7.5.0-SNAPSHOT

7.5.0-SNAPSHOT still generates separate duplicate nested classes for the Vegetable types instead of a shared top-level class.


EDIT

Tried it with 7.5.0 and 7.6.0-SNAPSHOT on 2024-04-23, still generates duplicate Vegatable types duplicated within the Palette and Basket types.

wing328 commented 6 months ago

can you please give it another try when you've time?

latest (docker tag) refers to the latest master

shorn commented 6 months ago
latest: Pulling from openapitools/openapi-generator-cli
Digest: sha256:6dff63bc9c685844906147c57880b022bdd5855a5d006b17bfdaeda8f81dc6bd
Status: Image is up to date for openapitools/openapi-generator-cli:latest
docker.io/openapitools/openapi-generator-cli:latest

Run on 2024-05-07, version reports 7.6.0-SNAPSHOT. Still generates two duplicate Vegetable types, each nested inside the VegetablePalette and VegetableBasket types.

ericdriggs commented 3 months ago

Still seeing enums as nested classes using java generator on 7.7.0

Using the following commands (url and packages changed)

java -jar openapi-generator-cli.jar generate \
   -i https://myserver.com/v3/api-docs.yaml \
   -g java \
   --library jersey3 \
   -p com.mypackage.qa. \
   --global-property apis,models,supportingFiles,apiTests=false,modelTests=false\
   --skip-validate-spec\
   -p additionalModelTypeAnnotations="@lombok.Data;@lombok.AllArgsConstructor;@lombok.experimental.SuperBuilder(toBuilder = true)"\
   --additional-properties apiPackage=com.mypackage.client\
,hideGenerationTimestamp=true\
,invokerPackage=com.mypackage.invoker\
,modelPackage=com.mypackage.pojos\
,sourceFolder=src/gen/java\
,useEnumCaseInsensitive=true
wing328 commented 2 months ago

my guess is that it's due to change in behaviour when parsing 3.1 spec with setResolve enabled as explained in the doc

https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---OpenAPI-3.1#resolving-dereferencing-bundling

as a workaround, please use 3.0 spec for the time being

wing328 commented 2 months ago

Another workaround is to enable resolve enum in inline schema resolver, e.g.

java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i https://raw.githubusercontent.com/shorn/openapi-fruitbat/main/shared-enum-3.1/src/main/openapi/shared-enum.yaml -o /tmp/java-enum/ --inline-schema-options RESOLVE_INLINE_ENUMS=true

doc: https://github.com/openapitools/openapi-generator/blob/master/docs/customization.md#inline-schema-naming

this works for me

ericdriggs commented 2 months ago

@wing328 Brilliant! --inline-schema-options RESOLVE_INLINE_ENUMS=true fixes it.