Skip to content

Commit 2590df6

Browse files
fix: adjust docs about RequiredMode.AUTO + small refactor
1 parent d126742 commit 2590df6

File tree

5 files changed

+69
-39
lines changed

5 files changed

+69
-39
lines changed

modules/swagger-annotations/src/main/java/io/swagger/v3/oas/annotations/media/Schema.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,11 @@
176176

177177
/**
178178
* Allows to specify the required mode (RequiredMode.AUTO, REQUIRED, NOT_REQUIRED)
179-
*
180-
* RequiredMode.AUTO: will let the library decide based on its heuristics.
179+
* RequiredMode.AUTO: the library decides using heuristics:
180+
* - Bean Validation / nullability annotations (@NotNull, @NonNull, @NotBlank, @NotEmpty) - required
181+
* - Optional - not required
182+
* - Primitive types (int, boolean, etc.) - not required unless annotated
183+
* - Other object fields without any constraints - not required
181184
* RequiredMode.REQUIRED: will force the item to be considered as required regardless of heuristics.
182185
* RequiredMode.NOT_REQUIRED: will force the item to be considered as not required regardless of heuristics.
183186
*

modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/ModelResolver.java

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2092,43 +2092,7 @@ private boolean resolveSubtypes(Schema model, BeanDescription bean, ModelConvert
20922092
ComposedSchema composedSchema = null;
20932093
if (!(subtypeModel instanceof ComposedSchema)) {
20942094
// create composed schema
2095-
// TODO #2312 - smarter way needs clone implemented in #2227
2096-
composedSchema = (ComposedSchema) new ComposedSchema()
2097-
.title(subtypeModel.getTitle())
2098-
.name(subtypeModel.getName())
2099-
.deprecated(subtypeModel.getDeprecated())
2100-
.additionalProperties(subtypeModel.getAdditionalProperties())
2101-
.description(subtypeModel.getDescription())
2102-
.discriminator(subtypeModel.getDiscriminator())
2103-
.exclusiveMaximum(subtypeModel.getExclusiveMaximum())
2104-
.exclusiveMinimum(subtypeModel.getExclusiveMinimum())
2105-
.externalDocs(subtypeModel.getExternalDocs())
2106-
.format(subtypeModel.getFormat())
2107-
.maximum(subtypeModel.getMaximum())
2108-
.maxItems(subtypeModel.getMaxItems())
2109-
.maxLength(subtypeModel.getMaxLength())
2110-
.maxProperties(subtypeModel.getMaxProperties())
2111-
.minimum(subtypeModel.getMinimum())
2112-
.minItems(subtypeModel.getMinItems())
2113-
.minLength(subtypeModel.getMinLength())
2114-
.minProperties(subtypeModel.getMinProperties())
2115-
.multipleOf(subtypeModel.getMultipleOf())
2116-
.not(subtypeModel.getNot())
2117-
.nullable(subtypeModel.getNullable())
2118-
.pattern(subtypeModel.getPattern())
2119-
.properties(subtypeModel.getProperties())
2120-
.readOnly(subtypeModel.getReadOnly())
2121-
.required(subtypeModel.getRequired())
2122-
.type(subtypeModel.getType())
2123-
.uniqueItems(subtypeModel.getUniqueItems())
2124-
.writeOnly(subtypeModel.getWriteOnly())
2125-
.xml(subtypeModel.getXml())
2126-
.extensions(subtypeModel.getExtensions());
2127-
2128-
if (subtypeModel.getExample() != null || subtypeModel.getExampleSetFlag()) {
2129-
composedSchema.example(subtypeModel.getExample());
2130-
}
2131-
composedSchema.setEnum(subtypeModel.getEnum());
2095+
composedSchema = ComposedSchema.from(subtypeModel);
21322096
} else {
21332097
composedSchema = (ComposedSchema) subtypeModel;
21342098
}

modules/swagger-core/src/test/java/io/swagger/v3/core/converting/ModelPropertyTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ public void testReadOnlyProperty() {
103103
public void testRequiredProperty() {
104104
final Map<String, Schema> models = ModelConverters.getInstance().readAll(RequiredFields.class);
105105
Schema model = models.get("RequiredFields");
106+
assertFalse(model.getRequired().contains("optionalField"));
107+
assertFalse(model.getRequired().contains("primitiveTypeWithoutConstraint"));
108+
assertTrue(model.getRequired().contains("primitiveTypeWithConstraint"));
106109
assertTrue(model.getRequired().contains("required"));
107110
assertFalse(model.getRequired().contains("notRequired"));
108111
assertTrue(model.getRequired().contains("notRequiredWithAnnotation"));

modules/swagger-core/src/test/java/io/swagger/v3/core/oas/models/RequiredFields.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import io.swagger.v3.oas.annotations.media.Schema;
44

55
import javax.validation.constraints.NotNull;
6+
import java.util.Optional;
67

78
public class RequiredFields {
89
@Schema(description = "required", required = true)
@@ -11,10 +12,20 @@ public class RequiredFields {
1112
@Schema(description = "not required")
1213
public Long notRequired;
1314

15+
@Schema(description = "Optional field")
16+
public Optional<Long> optionalField;
17+
1418
@Schema(description = "not required with annotation")
1519
@NotNull
1620
public Long notRequiredWithAnnotation;
1721

22+
@Schema(description = "primitive type without constraint")
23+
public long primitiveTypeWithoutConstraint;
24+
25+
@Schema(description = "primitive type with constraint")
26+
@NotNull
27+
public long primitiveTypeWithConstraint;
28+
1829
@Schema(description = "mode auto", requiredMode = Schema.RequiredMode.AUTO)
1930
public Long modeAuto;
2031

modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/ComposedSchema.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,55 @@
66

77
public class ComposedSchema extends Schema<Object> {
88

9+
public static ComposedSchema from(Schema subtypeModel) {
10+
ComposedSchema composedSchema = new ComposedSchema();
11+
copySchemaProperties(composedSchema, subtypeModel);
12+
13+
14+
if (shouldSetExample(subtypeModel)) {
15+
composedSchema.example(subtypeModel.getExample());
16+
}
17+
composedSchema.setEnum(subtypeModel.getEnum());
18+
return composedSchema;
19+
}
20+
21+
private static void copySchemaProperties(ComposedSchema target, Schema source) {
22+
target.title(source.getTitle())
23+
.name(source.getName())
24+
.deprecated(source.getDeprecated())
25+
.additionalProperties(source.getAdditionalProperties())
26+
.description(source.getDescription())
27+
.discriminator(source.getDiscriminator())
28+
.exclusiveMaximum(source.getExclusiveMaximum())
29+
.exclusiveMinimum(source.getExclusiveMinimum())
30+
.externalDocs(source.getExternalDocs())
31+
.format(source.getFormat())
32+
.maximum(source.getMaximum())
33+
.maxItems(source.getMaxItems())
34+
.maxLength(source.getMaxLength())
35+
.maxProperties(source.getMaxProperties())
36+
.minimum(source.getMinimum())
37+
.minItems(source.getMinItems())
38+
.minLength(source.getMinLength())
39+
.minProperties(source.getMinProperties())
40+
.multipleOf(source.getMultipleOf())
41+
.not(source.getNot())
42+
.nullable(source.getNullable())
43+
.pattern(source.getPattern())
44+
.properties(source.getProperties())
45+
.readOnly(source.getReadOnly())
46+
.required(source.getRequired())
47+
.type(source.getType())
48+
.uniqueItems(source.getUniqueItems())
49+
.writeOnly(source.getWriteOnly())
50+
.xml(source.getXml())
51+
.extensions(source.getExtensions());
52+
}
53+
54+
55+
private static boolean shouldSetExample(Schema model) {
56+
return model.getExample() != null || model.getExampleSetFlag();
57+
}
958

1059
@Override
1160
public String toString() {

0 commit comments

Comments
 (0)