domaindrivendev / Swashbuckle.AspNetCore

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

Minimal apis don't show up if GetSwaggerAsyc is called too early #2774

Open hahn-kev opened 7 months ago

hahn-kev commented 7 months ago

Swashbuckle version 6.4 and 6.5 (didn't test others).

  1. Generate a new minimal api project
  2. add await app.Services.GetRequiredService<IAsyncSwaggerProvider>().GetSwaggerAsync("v1"); just before app.Run() in program.cs
  3. Weather api does not show up in swagger

now the default weather api doesn't show up in swagger. Here's a full copy of the source:

using Swashbuckle.AspNetCore.Swagger;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

var summaries = new[]
{
    "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
app.UseRouting();
app.MapGet("/weatherforecast",
        () =>
        {
            var forecast = Enumerable.Range(1, 5).Select(index =>
                    new WeatherForecast(
                        DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
                        Random.Shared.Next(-20, 55),
                        summaries[Random.Shared.Next(summaries.Length)]
                    ))
                .ToArray();
            return forecast;
        })
    .WithName("GetWeatherForecast")
    .WithOpenApi();
await app.Services.GetRequiredService<IAsyncSwaggerProvider>().GetSwaggerAsync("v1");
app.Run();

public record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
    public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}

it seems like there's a race condition with calling GetSwaggerAsync too early where the minimal apis don't show up. MVC Controllers will show up correctly. The reason I'm doing this is to validate that we can generate a swagger doc on startup when devs are working. In my case I put it in a service and called generate after a 5 second delay to work around the issue.

martincostello commented 6 months ago

The reason I'm doing this is to validate that we can generate a swagger doc

If it were me, I'd use an integration test to validate this.

I wonder if the endpoints are lazily initialized on first use (or after Run()), so we can't "see" them yet.

haefele commented 4 months ago

Same problem happens to me when using <OpenApiGenerateDocumentsOnBuild>true</OpenApiGenerateDocumentsOnBuild> in my csproj.

haefele commented 4 months ago

Turns out, I could fix the issue by upgrading Microsoft.Extensions.ApiDescription.Server to the newest version. Right now it seems like version 6.0.5 is referenced. Once I upgraded it to a 8.0.x version, it worked again in my .NET 8 project.

Microsoft.Extensions.ApiDescription.Server seems to be backwards compatible, so maybe it would be a good idea to bump the version of this reference in Swashbuckle.AspNetCore.

github-actions[bot] commented 2 months ago

This issue is stale because it has been open for 60 days with no activity. It will be automatically closed in 14 days if no further updates are made.

1EDExg0ffyXfTEqdIUAYNZGnCeajIxMWd2vaQeP commented 2 months ago

bump

github-actions[bot] commented 2 weeks ago

This issue is stale because it has been open for 60 days with no activity. It will be automatically closed in 14 days if no further updates are made.