domaindrivendev / Swashbuckle.AspNetCore

Swagger tools for documenting API's built on ASP.NET Core
MIT License
5.26k stars 1.32k forks source link

second level inheritance for UseOneOfForPolymorphism #3155

Closed k0ka closed 1 week ago

k0ka commented 1 week ago

The issue or feature being addressed

The UseAllOfForInheritance option of schema generator only accounts for direct parents. It makes impossible to generate correct discriminator information for a big inheritance tree.

Example

data class structure:

[SwaggerDiscriminator("discriminator")]
[SwaggerSubType(typeof(SubSubType), DiscriminatorValue = nameof(SubSubType))]
abstract public class BaseType
{
}

abstract public class SubType : BaseType
{
}

public class SubSubType : SubType
{
    public int Property { get; set; }
}

Swagger generator options:

builder.Services.AddSwaggerGen(
    options =>
    {
        options.UseAllOfForInheritance();
        options.UseOneOfForPolymorphism();
        options.EnableAnnotations(true, true);
    });

Generated components of the json:

"components": {
    "schemas": {
      "SubSubType": {
        "type": "object",
        "properties": {
          "property": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      }
    }
  }

It doesn't include discriminator and BaseType definition.

If we remove SubType and make SubSubType child of BaseType we would get the expected generated components:

"components": {
    "schemas": {
      "BaseType": {
        "required": [
          "discriminator"
        ],
        "type": "object",
        "properties": {
          "discriminator": {
            "type": "string"
          }
        },
        "additionalProperties": false,
        "discriminator": {
          "propertyName": "discriminator",
          "mapping": {
            "SubSubType": "#/components/schemas/SubSubType"
          }
        }
      },
      "SubSubType": {
        "allOf": [
          {
            "$ref": "#/components/schemas/BaseType"
          },
          {
            "type": "object",
            "properties": {
              "property": {
                "type": "integer",
                "format": "int32"
              }
            },
            "additionalProperties": false
          }
        ]
      }
    }
  }

Details on the issue fix or feature implementation

This PR checks all parents until it finds the one which has this class defined as sub type. I added same assertions to test with one level assertions.

codecov-commenter commented 1 week ago

:warning: Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

All modified and coverable lines are covered by tests :white_check_mark:

Project coverage is 84.51%. Comparing base (8ea0461) to head (daeadcb).

:exclamation: Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files ```diff @@ Coverage Diff @@ ## master #3155 +/- ## ========================================== + Coverage 83.25% 84.51% +1.25% ========================================== Files 76 76 Lines 3142 3144 +2 Branches 526 527 +1 ========================================== + Hits 2616 2657 +41 + Misses 526 487 -39 ``` | [Flag](https://app.codecov.io/gh/domaindrivendev/Swashbuckle.AspNetCore/pull/3155/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Richard+Morris) | Coverage Δ | | |---|---|---| | [Linux](https://app.codecov.io/gh/domaindrivendev/Swashbuckle.AspNetCore/pull/3155/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Richard+Morris) | `83.26% <100.00%> (+0.01%)` | :arrow_up: | | [Windows](https://app.codecov.io/gh/domaindrivendev/Swashbuckle.AspNetCore/pull/3155/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Richard+Morris) | `84.47% <100.00%> (+1.21%)` | :arrow_up: | | [macOS](https://app.codecov.io/gh/domaindrivendev/Swashbuckle.AspNetCore/pull/3155/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Richard+Morris) | `83.26% <100.00%> (+0.01%)` | :arrow_up: | Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Richard+Morris#carryforward-flags-in-the-pull-request-comment) to find out more.

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.


🚨 Try these New Features:

k0ka commented 1 week ago

Hello,

I added this case to NswagClientExample because it was the only integration test which enabled inheritance and polymorphic annotations. Also, I found a problem in Annotation handler and fixed it. It was using only direct parent annotations to get type value.