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

Discriminated schema with shared ancestor shows invalid mapping options #2678

Open
milesizzo opened this issue Apr 1, 2025 · 2 comments
Open

Comments

@milesizzo
Copy link

Describe the bug

If a discriminated schema shares a common ancestor (schema) with another discriminated schema, extra schemas are shown in the UI (namely the two discriminated schemas).

Expected behavior

I would expect only the types listed in the mapping section to be shown.

Minimal reproducible OpenAPI snippet(if possible)

{
  "openapi": "3.0.1",
  "info": {
    "title": "My API",
    "version": "v1"
  },
  "paths": {
    "/animals": {
      "post": {
        "summary": "Create an animal",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAnimalReqDto"
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "CreateAnimalReqDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "mammal": {
            "$ref": "#/components/schemas/MammalDto"
          },
          "reptile": {
            "$ref": "#/components/schemas/ReptileDto"
          }
        }
      },
      "AnimalDto": {
        "type": "object"
      },
      "MammalDto": {
        "allOf": [
          {
            "$ref": "#/components/schemas/AnimalDto"
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "type": "string"
              }
            },
            "discriminator": {
              "propertyName": "type",
              "mapping": {
                "cat": "#/components/schemas/CatDto",
                "dog": "#/components/schemas/DogDto"
              }
            }
          }
        ]
      },
      "ReptileDto": {
        "allOf": [
          {
            "$ref": "#/components/schemas/AnimalDto"
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "type": "string"
              }
            },
            "discriminator": {
              "propertyName": "type",
              "mapping": {
                "lizard": "#/components/schemas/LizardDto"
              }
            }
          }
        ]
      },
      "CatDto": {
        "allOf": [
          {
            "$ref": "#/components/schemas/MammalDto"
          },
          {
            "type": "object"
          }
        ]
      },
      "DogDto": {
        "allOf": [
          {
            "$ref": "#/components/schemas/MammalDto"
          },
          {
            "type": "object"
          }
        ]
      },
      "LizardDto": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ReptileDto"
          },
          {
            "type": "object"
          }
        ]
      }
    }
  }
}

Screenshots

Image

(highlighted discriminator values are invalid)

Additional context

N/A

@milesizzo
Copy link
Author

I assume this is the same issue, but will document it here anyway. Using AnimalDto as the base discriminated type and MammalDto/ReptileDto as intermediate types:

{
  "openapi": "3.0.1",
  "info": {
    "title": "My API",
    "version": "v1"
  },
  "paths": {
    "/animals": {
      "post": {
        "summary": "Create an animal",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAnimalReqDto"
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "CreateAnimalReqDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "animal": {
            "$ref": "#/components/schemas/AnimalDto"
          }
        }
      },
      "AnimalDto": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string"
          }
        },
        "discriminator": {
          "propertyName": "type",
          "mapping": {
            "cat": "#/components/schemas/CatDto",
            "dog": "#/components/schemas/DogDto",
            "lizard": "#/components/schemas/LizardDto"
          }
        }
      },
      "MammalDto": {
        "allOf": [
          {
            "$ref": "#/components/schemas/AnimalDto"
          },
          {
            "type": "object"
          }
        ]
      },
      "ReptileDto": {
        "allOf": [
          {
            "$ref": "#/components/schemas/AnimalDto"
          },
          {
            "type": "object"
          }
        ]
      },
      "CatDto": {
        "allOf": [
          {
            "$ref": "#/components/schemas/MammalDto"
          },
          {
            "type": "object"
          }
        ]
      },
      "DogDto": {
        "allOf": [
          {
            "$ref": "#/components/schemas/MammalDto"
          },
          {
            "type": "object"
          }
        ]
      },
      "LizardDto": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ReptileDto"
          },
          {
            "type": "object"
          }
        ]
      }
    }
  }
}

Produces the following UI:

Image

@milesizzo
Copy link
Author

Perhaps this is my misunderstanding of how to structure a polymorphic schema:

I assume this is the same issue, but will document it here anyway. Using AnimalDto as the base discriminated type and MammalDto/ReptileDto as intermediate types:

Using this example, I removed the inclusion of AnimalDto from MammalDto and ReptileDto:

// ... snip ...
      "AnimalDto": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string"
          }
        },
        "discriminator": {
          "propertyName": "type",
          "mapping": {
            "cat": "#/components/schemas/CatDto",
            "dog": "#/components/schemas/DogDto",
            "lizard": "#/components/schemas/LizardDto"
          }
        }
      },
      "MammalDto": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string"
          }
        }
      },
      "ReptileDto": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string"
          }
        }
      },
// ... snip ...

This produced the correct result:

Image

Albeit at the expense of redefining common properties in each mapped schema.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant