diff --git a/README.md b/README.md index dddec7d369..bc16a72696 100644 --- a/README.md +++ b/README.md @@ -654,6 +654,21 @@ components: type: string example: "94022" ``` +#### 5. explicitObjectSchema: + +```java +ParseOptions parseOptions = new ParseOptions(); +parseOptions.setResolve(true); // implicit +parseOptions.setResolveFully(true); +parseOptions.setResolveCombinators(false); +parseOptions.setExplicitObjectSchema(false); // default is true +final OpenAPI openAPI = new OpenAPIV3Parser().read("a.yaml", null, parseOptions); +``` + +This option allows you to customize the processing of schema properties when the type is not specified. By default it is set to `true`. +- `true` : when the type is not defined for property, ‘object’ is set. +- `false` : the property remains undefined when no type is specified +It's only applied when `resolveFully` is set to `true`. ### Extensions This project has a core artifact--`swagger-parser`, which uses Java Service Provider Interface (SPI) so additional extensions can be added. diff --git a/modules/swagger-parser-core/src/main/java/io/swagger/v3/parser/core/models/ParseOptions.java b/modules/swagger-parser-core/src/main/java/io/swagger/v3/parser/core/models/ParseOptions.java index 777d4877b3..0bdbebd5e0 100644 --- a/modules/swagger-parser-core/src/main/java/io/swagger/v3/parser/core/models/ParseOptions.java +++ b/modules/swagger-parser-core/src/main/java/io/swagger/v3/parser/core/models/ParseOptions.java @@ -22,6 +22,7 @@ public class ParseOptions { private List remoteRefAllowList; private List remoteRefBlockList; private boolean explicitStyleAndExplode = true; + private boolean explicitObjectSchema = true; public boolean isResolve() { @@ -179,4 +180,12 @@ public void setExplicitStyleAndExplode(boolean explicitStyleAndExplode) { this.explicitStyleAndExplode = explicitStyleAndExplode; } + public boolean isExplicitObjectSchema() { + return explicitObjectSchema; + } + + public void setExplicitObjectSchema(boolean explicitObjectSchema) { + this.explicitObjectSchema = explicitObjectSchema; + } + } diff --git a/modules/swagger-parser-v2-converter/src/main/java/io/swagger/v3/parser/converter/SwaggerConverter.java b/modules/swagger-parser-v2-converter/src/main/java/io/swagger/v3/parser/converter/SwaggerConverter.java index d4d2b189b3..019aeaf6fd 100644 --- a/modules/swagger-parser-v2-converter/src/main/java/io/swagger/v3/parser/converter/SwaggerConverter.java +++ b/modules/swagger-parser-v2-converter/src/main/java/io/swagger/v3/parser/converter/SwaggerConverter.java @@ -104,7 +104,7 @@ private SwaggerParseResult readResult(SwaggerDeserializationResult result, List< SwaggerParseResult out = convert(result); if (out != null && out.getOpenAPI() != null && options != null) { if (options.isResolveFully()) { - new ResolverFully(options.isResolveCombinators()).resolveFully(out.getOpenAPI()); + new ResolverFully(options).resolveFully(out.getOpenAPI()); } if (options.isFlatten()) { try { diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/OpenAPIV3Parser.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/OpenAPIV3Parser.java index b1a5d844bc..74e9af6313 100644 --- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/OpenAPIV3Parser.java +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/OpenAPIV3Parser.java @@ -227,7 +227,7 @@ private SwaggerParseResult resolve(SwaggerParseResult result, List schemas; private Map resolvedModels = new HashMap<>(); private Map examples; @@ -493,7 +503,7 @@ public Schema resolveSchema(Schema schema) { Schema property = updated.get(key); if (property.getProperties() != model.getProperties()) { - if (!hasSchemaType(property)) { + if (!hasSchemaType(property) && parseOptions.isExplicitObjectSchema()) { if (SpecVersion.V30.equals(property.getSpecVersion())) { property.setType("object"); } else { diff --git a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIResolverTest.java b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIResolverTest.java index 6516c95cc8..ff1b353014 100644 --- a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIResolverTest.java +++ b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIResolverTest.java @@ -45,6 +45,7 @@ import org.testng.Assert; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import java.io.File; @@ -597,7 +598,7 @@ public void testSelfReferenceResolution()throws Exception { options.setResolveFully(true); OpenAPI openAPI = new OpenAPIV3Parser().readContents(yaml,auths,options).getOpenAPI(); - ResolverFully resolverUtil = new ResolverFully(); + ResolverFully resolverUtil = new ResolverFully(options); resolverUtil.resolveFully(openAPI); @@ -643,7 +644,7 @@ public void testIssue85() { options.setResolveFully(true); OpenAPI openAPI = new OpenAPIV3Parser().readContents(yaml,auths,options).getOpenAPI(); - ResolverFully resolverUtil = new ResolverFully(); + ResolverFully resolverUtil = new ResolverFully(options); resolverUtil.resolveFully(openAPI); Parameter param = openAPI.getPaths().get("/test/method").getPost().getParameters().get(0); @@ -1475,5 +1476,29 @@ public void testResolveArraySchemaItemsNullPointerException() { final OpenAPI output = new OpenAPIV3Parser().read(actualLocation, null, options); new OpenAPIResolver(output, null, actualLocation).resolve(); } + + @Test(dataProvider = "explicitObjectSchemaProvider") + public void testIssue2113(boolean explicitObjectSchema) { + ParseOptions options = new ParseOptions(); + options.setResolve(true); + options.setResolveFully(true); + options.setExplicitObjectSchema(explicitObjectSchema); + + OpenAPI openAPI = new OpenAPIV3Parser().readLocation("issue_2113.yaml", auths, options).getOpenAPI(); + ObjectSchema schema = (ObjectSchema) openAPI.getPaths().get("/foo").getPost().getRequestBody().getContent().get("application/json").getSchema(); + if (explicitObjectSchema) { + assertEquals(schema.getProperties().get("goo").getType(), "object"); + } else { + assertNull(schema.getProperties().get("goo").getType()); + } + } + + @DataProvider(name = "explicitObjectSchemaProvider") + public Object[][] explicitObjectSchemaProvider() { + return new Object[][] { + { true }, + { false } + }; + } } diff --git a/modules/swagger-parser-v3/src/test/resources/issue_2113.yaml b/modules/swagger-parser-v3/src/test/resources/issue_2113.yaml new file mode 100644 index 0000000000..854f1f4f13 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/issue_2113.yaml @@ -0,0 +1,28 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Issue X +servers: + - url: http://petstore.swagger.io/api +paths: + /foo: + post: + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ObjectType' + required: true + responses: + 200: + description: ok +components: + schemas: + ObjectType: + type: object + allOf: + - $ref: "#/components/schemas/NoType" + NoType: + properties: + goo: + title: "Boo" \ No newline at end of file