swagger-api / swagger-api/swagger-core
BUG @Schema#allowableValues adds enums but does not remove existing enum references when resolving enum as references and using open api 3.1.0
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 7.5k
- Forks
- 2.3k
- Avg merge
- 18h 1m
- Merged PRs (30d)
- 10
Description
Problem
When generating OpenAPI 3.1.0 spec and setting ModelResolver#enumsAsRef to true the @Schema#allowableValues annotation on an enum property is not processed correctly. The expected behaviour is that the generated property has no enum schema reference but instead uses the enum values which have been specified through @Schema#allowableValues. Instead both the enums values specified through allowableValues and the original enum schema reference are generated. Note that this is not the same issue as #2949 because when using open api 3.1.0 but not resolving enums as reference that issues is fixed (i.e the entries specified in allwoableValues override the existing enum definition rather than adding to it).
Expected behaviour
@Schema#allowableValue overrides any schema reference to enums when generating OAS3.1
Reproducer
The issues is reproduced in the following test:
@Test(description = "Shows that allowableValues from @Schema is not processed correctly when using oas 3.1.0 and resolving enums as refs")
public void testModelUsingAllowableValuesWhenGeneratingEnumAsRefForOas31() {
// by default resolve enums as reference types
ModelResolver.enumsAsRef = true;
String expectedYaml = "PojoUsingAllowableValues:\n" +
" properties:\n" +
" enumField:\n" +
" type: string\n" +
// here we expect to have no $ref to the original enum schema (i.e MyEnum) but instead a reference is generated
" enum:\n" +
" - A\n" +
" - B\n";
// fails as in addition to the enum values also a reference to the original enum is added
Map<String, io.swagger.v3.oas.models.media.Schema> stringSchemaMap = ModelConverters.getInstance(true).readAll(PojoUsingAllowableValues.class);
SerializationMatchers.assertEqualsToYaml31(stringSchemaMap, expectedYaml);
}
private static final class PojoUsingAllowableValues {
@Schema(allowableValues = {"A", "B"})
private MyEnum enumField;
public MyEnum getEnumField() {
return enumField;
}
public void setEnumField(MyEnum enumField) {
this.enumField = enumField;
}
}
private enum MyEnum {
A, B, C;
}
Investigation with proposed solution
Looking at the AnnotationsUtils.getSchemaFromAnnotation code (which is where information to @Schema annotations are reconciled with oas 3.1.0 models generated for properties, see ModelResolver#719), it looks like when allowableValues are processed (AnnotationsUtils#806), any information related to references should be removed. That would mean that the code would look something like the following:
if (schema.allowableValues().length > 0) {
schemaObject.setEnum(Arrays.asList(schema.allowableValues()));
// remove any existing reference as otherwise it would be conflicting with the enum entries
schemaObject.set$ref(null);
}
Would this solution be valid or is there any scenario which I am missing where one would want both enum and $ref set while processing @Schema#allowableValues?
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 AnnotationsUtils.getSchemaFromAnnotation where @Schema allowableValues are processed, and review the related ModelResolver#719 flow. Run the provided testModelUsingAllowableValuesWhenGeneratingEnumAsRefForOas31 reproducer and compare its YAML with the expected output. Done means the generated enumField schema contains A and B without a reference to MyEnum.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, openapi
- Domain
- api
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 48/100