Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

$ref not fully resolved for object with no type #1433

Closed
phiz71 opened this issue Sep 30, 2020 · 1 comment · Fixed by #1434
Closed

$ref not fully resolved for object with no type #1433

phiz71 opened this issue Sep 30, 2020 · 1 comment · Fixed by #1434

Comments

@phiz71
Copy link
Contributor

phiz71 commented Sep 30, 2020

Hi, I want to parse an openAPI document with $ref but even with the resolveFully option, it does not work.

Problem

I want to parse this document

openapi: 3.0.0
info:
  title: no type resolution
  version: 1.0.0
paths:
  /foo:
    post:
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FooInput'
      responses:
        '200':
          description: subscription successfully created
components:
  schemas:
    FooInput:
      properties:
        bar:
          type: string
        input:
          $ref: '#/components/schemas/BazInput'
    BazInput:
      properties:
        baz:
          type: string

I use the resolveFully option and I expect to have this result:

openapi: 3.0.0
info:
  title: no type resolution
  version: 1.0.0
servers:
- url: /
paths:
  /foo:
    post:
      requestBody:
        content:
          application/json:
            schema:
              properties:
                bar:
                  type: string
                input:
                  properties:
                    baz:
                      type: string
        required: true
      responses:
        "200":
          description: subscription successfully created
components:
  schemas:
    FooInput:
      properties:
        bar:
          type: string
        input:
          properties:
            baz:
              type: string
    BazInput:
      type: object
      properties:
        baz:
          type: string

But instead, the FooInput.input ref is not resolved.

openapi: 3.0.0
info:
  title: no type resolution
  version: 1.0.0
servers:
- url: /
paths:
  /foo:
    post:
      requestBody:
        content:
          application/json:
            schema:
              properties:
                bar:
                  type: string
                input:
                  $ref: '#/components/schemas/BazInput'
        required: true
      responses:
        "200":
          description: subscription successfully created
components:
  schemas:
    FooInput:
      properties:
        bar:
          type: string
        input:
          $ref: '#/components/schemas/BazInput'
    BazInput:
      properties:
        baz:
          type: string

Analysis

After some test, i found out that if I add type: object to either FooInput schema or BazInput schema, the resolution is correct.

If i add type: object in FooInput, the resolver execute this code (io.swagger.v3.parser.util.ResolverFully):
https://github.com/swagger-api/swagger-parser/blob/master/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/ResolverFully.java#L323

if (schema instanceof ObjectSchema) {
  ObjectSchema obj = (ObjectSchema) schema;
  if(obj.getProperties() != null) {
    Map<String, Schema> updated = new LinkedHashMap<>();
    for(String propertyName : obj.getProperties().keySet()) {
      Schema innerProperty = obj.getProperties().get(propertyName);
      // reference check
      if(schema != innerProperty) {
        updated.put(propertyName, resolveSchemaProperty(propertyName, innerProperty));
      }
    }
    obj.setProperties(updated);
  }
  return obj;
}

If i add type: object in BazInput, the resolver execute this code (io.swagger.v3.parser.util.ResolverFully):
https://github.com/swagger-api/swagger-parser/blob/master/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/ResolverFully.java#L398

if(property instanceof ObjectSchema) {
  ObjectSchema op = (ObjectSchema) property;
  if (op.getProperties() != model.getProperties()) {
    if (property.getType() == null) {
      property.setType("object");
    }
    model.addProperties(key, property);
  } else {
    LOGGER.debug("not adding recursive properties, using generic object");
    ObjectSchema newSchema = new ObjectSchema();
    model.addProperties(key, newSchema);
  }
}

Proposition

I think there is a problem in the second part of code.

    if (property.getType() == null) {
      property.setType("object");
    }

Because if property is an instance of ObjectSchema, it means property.getType() is not null.
So I propose to remove the if and to keep only:

//if(property instanceof ObjectSchema) {
//  ObjectSchema op = (ObjectSchema) property;
  if (property.getProperties() != model.getProperties()) {
    if (property.getType() == null) {
      property.setType("object");
    }
    model.addProperties(key, property);
  } else {
    LOGGER.debug("not adding recursive properties, using generic object");
    ObjectSchema newSchema = new ObjectSchema();
    model.addProperties(key, newSchema);
  }
//}

If you are ok with this, I can create a PR.

@gracekarina
Copy link
Contributor

gracekarina commented Sep 30, 2020

hey @phiz71, please create the PR and we will test the impact in other OSS projects dependant of parser, and see if anything breaks 😉
Thanks!

phiz71 added a commit to phiz71/swagger-parser that referenced this issue Sep 30, 2020
phiz71 added a commit to phiz71/swagger-parser that referenced this issue Oct 1, 2020
phiz71 added a commit to phiz71/swagger-parser that referenced this issue Oct 1, 2020
kerrykimbrough pushed a commit to kerrykimbrough/swagger-parser that referenced this issue Nov 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants