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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions