Skip to content

7.1.2 replaces schema reference with copy of schema #198

@natehitze-eventlink

Description

@natehitze-eventlink

After an upgrade I was trying to debug why our OpenAPI document changed in a way that prevented tools from knowing which classes were nested. It's easier to explain with an example.

Packages:

<PackageReference Include="FluentValidation.AspNetCore" Version="11.3.1" />
<PackageReference Include="MicroElements.Swashbuckle.FluentValidation" Version="7.1.2" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.5"/>
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.1.5" />

Here's the Program.cs:

using FluentValidation;
using FluentValidation.AspNetCore;
using MicroElements.Swashbuckle.FluentValidation.AspNetCore;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddFluentValidationAutoValidation();
builder.Services.AddValidatorsFromAssemblyContaining<Program>();
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddFluentValidationRulesToSwagger();
builder.Services.AddSwaggerGen();

var app = builder.Build();
app.UseSwagger();
app.MapGet("/getperson", () => new Person());
app.Run();

public class Person
{
    public Address Address { get; set; }
}

public class PersonValidator : AbstractValidator<Person>
{
    public PersonValidator()
    {
        RuleFor(x => x.Address)
            .NotEmpty()
            .SetValidator(new AddressValidator());
    }
}

public class Address
{
    public string Street { get; set; }
}

public class AddressValidator : AbstractValidator<Address>
{
    public AddressValidator()
    {
        RuleFor(x => x.Street).NotEmpty();
    }   
}

On 7.1.2 you get this document:

{
  "openapi": "3.0.4",
  "info": {
    "title": "ReproWeb",
    "version": "1.0"
  },
  "paths": {
    "/getperson": {
      "get": {
        "tags": [
          "ReproWeb"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Person"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Address": {
        "required": [
          "street"
        ],
        "type": "object",
        "properties": {
          "street": {
            "minLength": 1,
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "Person": {
        "required": [
          "address"
        ],
        "type": "object",
        "properties": {
          "address": {
            "required": [
              "street"
            ],
            "type": "object",
            "properties": {
              "street": {
                "minLength": 1,
                "type": "string"
              }
            },
            "additionalProperties": false
          }
        },
        "additionalProperties": false
      }
    }
  },
  "tags": [
    {
      "name": "ReproWeb"
    }
  ]
}

components.schemas['Person'].properties['address'] is a full object.

In 7.1.1 you get this:

{
  "openapi": "3.0.4",
  "info": {
    "title": "ReproWeb",
    "version": "1.0"
  },
  "paths": {
    "/getperson": {
      "get": {
        "tags": [
          "ReproWeb"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Person"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Address": {
        "required": [
          "street"
        ],
        "type": "object",
        "properties": {
          "street": {
            "minLength": 1,
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "Person": {
        "required": [
          "address"
        ],
        "type": "object",
        "properties": {
          "address": {
            "$ref": "#/components/schemas/Address"
          }
        },
        "additionalProperties": false
      }
    }
  },
  "tags": [
    {
      "name": "ReproWeb"
    }
  ]
}

where components.schemas['Person'].properties['address'] is back to being a $ref object.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions