Coder Social home page Coder Social logo

Comments (4)

glowcloud avatar glowcloud commented on June 12, 2024

The issue on the surface looks like it was introduced by 7300e6c but it seems like it actually uncovered a different issue, which you can see in Swagger Editor.

The names there are displayed correctly:

Screenshot 2024-04-08 at 15 35 55

but if we actually expand the schemas:
Screenshot 2024-04-08 at 15 38 58

you can see that additionalData from FirstOneOf is missing and the references are also not resolved properly.

The resolved subtree for OneOfParent:

{
    "title": "OneOfParent",
    "properties": {
        "additionalData": {
            "oneOf": [
                {
                    "$ref": "http://localhost:3200/examples/regressionJson.json#/components/schemas/OneOfParent",
                    "properties": {
                        "numberProp": {
                            "type": "number",
                            "example": "1"
                        }
                    },
                    "type": "object",
                    "title": "FirstOneOf",
                    "$$ref": "http://localhost:3200/examples/regressionJson.json#/components/schemas/FirstOneOf"
                },
                {
                    "$ref": "http://localhost:3200/examples/regressionJson.json#/components/schemas/OneOfParent",
                    "properties": {
                        "person": {
                            "properties": {
                                "id": {
                                    "type": "string"
                                }
                            },
                            "type": "object"
                        }
                    },
                    "type": "object",
                    "title": "SecondOneOf",
                    "$$ref": "http://localhost:3200/examples/regressionJson.json#/components/schemas/SecondOneOf"
                },
                {
                    "$ref": "http://localhost:3200/examples/regressionJson.json#/components/schemas/OneOfParent",
                    "properties": {
                        "person": {
                            "properties": {
                                "id": {
                                    "type": "string"
                                },
                                "name": {
                                    "type": "string"
                                },
                                "surname": {
                                    "type": "string"
                                }
                            },
                            "type": "object"
                        }
                    },
                    "type": "object",
                    "title": "ThirdOneOf",
                    "$$ref": "http://localhost:3200/examples/regressionJson.json#/components/schemas/ThirdOneOf"
                }
            ]
        }
    },
    "type": "object"
}

We can see both the resolved $$ref and unresolved $ref - because of this the names are different and we only get the schema under $ref, as that was one of the changes in this commit 7300e6c

If we expand FirstOneOf first and then OneOfParent, we'll get this:

Screenshot 2024-04-08 at 15 40 48

This looks to me like an issue with the resolver - perhaps with allOf and circular / unresolved references.

from swagger-ui.

glowcloud avatar glowcloud commented on June 12, 2024

In theory, we could pass fn to our Model component and use mergeJsonSchema - in place of

if ($ref) {
name = this.getModelName($ref)
const refSchema = this.getRefSchema(name)
if (Map.isMap(refSchema)) {
schema = refSchema.set("$$ref", $ref)
$$ref = $ref
} else {
schema = null
name = $ref
}
}

have something like this:

if ($ref) {
   const refName = this.getModelName($ref)
   const refSchema = this.getRefSchema(refName)
   if (Map.isMap(refSchema)) {
     schema = fromJS(fn.mergeJsonSchema(schema.toJS(), refSchema.toJS()))
     name = name || refName
     if (!$$ref) {
       schema = schema.set("$$ref", $ref)
       $$ref = $ref
     }
   } else if (!$$ref) {
     schema = null
     name = $ref
   }
 }

this will work for the spec in the issue:
Screenshot 2024-04-09 at 09 59 53

But it will not solve it for cases where we have more than one circular reference, as the $ref property will get replaced by the next defined $ref. To illustrate it, we can have this spec:

{
  "openapi": "3.0.0",
  "info": {
    "title": "Test",
    "description": "Test",
    "license": {
      "name": "Apache 2.0",
      "url": "https://www.apache.org/licenses/LICENSE-2.0.html"
    },
    "version": "1.0"
  },
  "servers": [
    {
      "url": "https://localhost:8000"
    }
  ],
  "components": {
    "schemas": {
      "Parent": {
        "title": "Parent",
        "properties": {
          "parentData": {
            "$ref": "#/components/schemas/OneOfParent"
          }
        },
        "type": "object"
      },
      "OneOfParent": {
        "title": "OneOfParent",
        "properties": {
          "additionalData": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/FirstOneOf"
              }
            ]
          }
        },
        "type": "object"
      },
      "FirstOneOf": {
        "title": "FirstOneOf",
        "type": "object",
        "allOf": [
          {
            "$ref": "#/components/schemas/Parent"
          },
          {
            "$ref": "#/components/schemas/OneOfParent"
          },
          {
            "properties": {
              "numberProp": {
                "type": "number",
                "example": "1"
              }
            },
            "type": "object"
          }
        ]
      }
    }
  }
}

and our rendered model will be missing parentData:
Screenshot 2024-04-09 at 09 56 44

If we swap the order of references in allOf in FirstOneOf:

"FirstOneOf": {
      "title": "FirstOneOf",
      "type": "object",
      "allOf": [
        {
          "$ref": "#/components/schemas/OneOfParent"
        },
        {
          "$ref": "#/components/schemas/Parent"
        },
        {
          "properties": {
            "numberProp": {
              "type": "number",
              "example": "1"
            }
          },
          "type": "object"
        }
      ]
    }

This time additionalData will be missing:
Screenshot 2024-04-09 at 09 57 25

It looks to me like we would somehow need to keep these unresolved $refs in an array (as $ref: [<unresolved_ref_0>, <unresolved_ref_1>, ...]) instead of only having a string there, that gets replaced when we get another $ref

from swagger-ui.

char0n avatar char0n commented on June 12, 2024
  • we will assume that every schema with $ref field and one or more additional fields is a result of allOf keyword merge
  • given that Reference Object cannot have any additional fields than $ref, the assumption is almost correct
  • we will use Immutable.mergeDeep to merge the referenced schema with the referencing one (which makes it compatible with swagger-client allOf specmap plugin)
  • this can introduce possible circular references (cycles) again into the deferenced tree

from swagger-ui.

char0n avatar char0n commented on June 12, 2024

Addressed in #9794

from swagger-ui.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.