RicoSuter / NSwag

The Swagger/OpenAPI toolchain for .NET, ASP.NET Core and TypeScript.
http://NSwag.org
MIT License
6.69k stars 1.23k forks source link

No operations defined in spec when using minimal #3526

Open cheoalfredo opened 3 years ago

cheoalfredo commented 3 years ago

Hi, i'm creating a minimal api with https://dotnetthoughts.net/minimal-api-in-aspnet-core-mvc6/, i'm setting up nswag with :

var builder = WebApplication.CreateBuilder(args);
var config = builder.Configuration;

builder.Services.AddMvc();
builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "Api", Version = "v1" });
});

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
    app.UseSwagger();
    app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Api v1"));
}

app.MapGet("/api/person/{id:guid}", async ctx =>
{    
    Guid? id = Guid.Parse(ctx.Request.RouteValues["id"].ToString());
    if (id is null)
    {
        ctx.Response.StatusCode = 404;
        return;
    }

   await ctx.Response.WriteAsJsonAsync(await ctx.RequestServices.GetService<IMediator>()
        .Send(new Application.Person.Queries.PersonQuery(Guid.Parse(id.ToString()))));

});

await app.RunAsync();

when i launch the api, i get the usual swagger page with the message "No operations defined in spec!" do i have to do anything else in order to get the openapi documentation generated ?

RicoSuter commented 3 years ago

Yes, because NSwag relies on the ASP.NET Core API Explorer which need to reflect on operations... you're setting up a procedural route handler which is not picked up by API Explorer (ie this probably only works with controllers).

SeppPenner commented 2 years ago

@RicoSuter I have tried your example with minimal API support from https://github.com/RicoSuter/NSwag/issues/3560#issuecomment-965630171. It works (but doesn't show method names, of course).

Is there any option to document the methods within minimal API handlers (or however these "controllers" can be called) if we don't use anonymous methods but a class with static methods?

E.g.

app.MapGet("/", (r) => Test.Something());

public class Test
{
    /// <summary>I am documented now.</summary>
    public static Task Something()
    {
        Task.FromResult("Hello there.");
    }
}

instead of

app.MapGet("/", (r) => Task.FromResult("Hello world!"));

Or is the only option to document the methods to use the known controller annotations like

[Route("api/nodes")]
[ApiController]
[OpenApiTag("Nodes", Description = "Node management.")]

and so on?

RicoSuter commented 2 years ago

@SeppPenner Isnt there an extension method WithName() to provide the operation name?

https://github.com/RicoSuter/NSwag/blob/801db8aa5e54fd548260cdaf27d79a3893c6b2bb/src/NSwag.Sample.NET60Minimal/Program.cs#L29

RicoSuter commented 2 years ago

@cheoalfredo btw, you're using Swashbuckle and not NSwag for spec generation (so issue is in the wrong repo or you switch to use NSwag)

SeppPenner commented 2 years ago

@SeppPenner Isnt there an extension method WithName() to provide the operation name?

https://github.com/RicoSuter/NSwag/blob/801db8aa5e54fd548260cdaf27d79a3893c6b2bb/src/NSwag.Sample.NET60Minimal/Program.cs#L29

Yeah, sorry. I found your example project in the samples... In my case, the issue was / is a bit more complex as I'm mixing HTTP1 ("The old controllers") and HTTP2 calls (GRPC services) on the same endpoint while also having another endpoint where only certain calls should be possible (I wanted to use the minimal API here, but I don't beleive that it's working like that in the concrete scenario). But the issue has nothing to do with NSwag directly right now 😄