RicoSuter / NSwag

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

Add support for `Microsoft.AspNetCore.OpenApi` strategy in NSwag #4163

Open captainsafia opened 1 year ago

captainsafia commented 1 year ago

In .NET 7, we introduced support for a new Microsoft.AspNeCore.OpenApi package that generates an OpenApiOperation definition for a given minimal API endpoint using its method info and metadata. Calling the following code, will generate an OpenApiOperation for the given endpoint and store it in the endpoints metadata.

using Microsoft.AspNetCore.OpenApi;

app.MapGet("/", () => ...)
  .WithOpenApi();

This OpenApi operation includes the same information that would've been generated by the ApiExplorer but is designed to be customizable, such as:

app.MapGet("/", () => ...)
  .WithOpenApi(operation =>
  {
    operation.Summary = "Some summary here";
  });

It's also meant to take higher precedence than operations derived from ApiExplorer. To support this in Swashbuckle, we currently favor the OpenApiOperation stored in metadata with the OpenApiDocument generated by SwaggerGen (see https://github.com/domaindrivendev/Swashbuckle.AspNetCore/pull/2404). We also patch in the OpenApiSchema generated by Swashbuckle.AspNetCore (see https://github.com/domaindrivendev/Swashbuckle.AspNetCore/pull/2441).

For NSwag, it might make sense to implement this as a separate MinimalAspNetCoreOpenApiDocumentGenerator to make the factoring a little cleaner.

amilcar-dev commented 1 year ago

Any update on this?

In .NET 6 there is any way to add the summary or description? I'm having issues with minimal api

Xyotic commented 1 year ago

Waiting for this too. The minimal API needs better documentation support

captainsafia commented 1 year ago

Any update on this?

In .NET 6 there is any way to add the summary or description? I'm having issues with minimal api

There's no out-of-box way to set these two in .NET 6. If you're using NSwag, you may want to take a look at using the annotation attributes.

LloydNicholson commented 1 year ago

I have created a basic reproduction of WithSummary not working using NSwag and working using Swashbuckle. This project is using .NET 7. MinimalApi.zip

vipwan commented 11 months ago

.NET8 is comming Any new ideas?

aunikitin commented 9 months ago

@RicoSuter hello, sorry for direct tagging you If you give more info there, I'll try to make a PR for fixing this.

It's really annoying now, that it's not clear how to use minimal api + nswag. WithName/WithDescription/WithSummary and other stuff do nothing in UI and it's a bit challenging to find such issues (that you're not able to add comments to API with Minimal Api and NSwag for now) in discussion

I'll give some examples On the 1st picture, it's common look of registration. I have multiple calls to different extensions. It's also tricky that group do nothing with UI while you don't use WithTags

image

My result. I expect to see at least description of my api. I also want WithGroupName to be used as group name.

image
KennethHoff commented 9 months ago

This is blocking me from using NSwag currently, so I had to temporarily revert to Swashbuckle despite that not having a commit in almost a year.

RicoSuter commented 9 months ago

Apparently ASP.NET Core/Microsoft does not just populate API Explorer with additional metadata but invented a new way to provide metadata OpenApiOperation metadata object... NSwag needs to also look at this and use this over API Explorer metadata...

captainsafia commented 9 months ago

@RicoSuter There's two aspects. to this:

The WithName and WithDescription extension methods populate EndpointMetadata which is accessible via the API explorer. https://github.com/domaindrivendev/Swashbuckle.AspNetCore/pull/2173 showcases how these values can be read from EndpointMetadata via the API explorer types.

The WithOpenApi extension method sets metadata in a similar way and you can access it via the same types. https://github.com/domaindrivendev/Swashbuckle.AspNetCore/pull/2404 showcases this.

patnym commented 7 months ago

If you're struggling with this you can add your own OperationProcessor to use the built in "WithOpenApi", "WithDescription" etc if you'd like.

Only tested with .NET 8

Here's an example:

public class DotnetOpenApiProcessor : IOperationProcessor
{
    public bool Process(OperationProcessorContext context)
    {
        if (context is not AspNetCoreOperationProcessorContext aspnetContext)
        {
            // Will still include this operation - set to false to exclude it.
            return true;
        }

        foreach (var metadata in aspnetContext.ApiDescription.ActionDescriptor.EndpointMetadata)
        {

            if (metadata is OpenApiOperation openApiMetadata)
            {
                context.OperationDescription.Operation.OperationId = openApiMetadata.OperationId;
                context.OperationDescription.Operation.IsDeprecated = openApiMetadata.Deprecated;
                context.OperationDescription.Operation.Summary = openApiMetadata.Summary;
                context.OperationDescription.Operation.Description = openApiMetadata.Description;
            }
            else if (metadata is EndpointSummaryAttribute summaryAttribute)
            {
                context.OperationDescription.Operation.Summary = summaryAttribute.Summary;
            }
            else if (metadata is EndpointDescriptionAttribute descriptionAttribute)
            {
                context.OperationDescription.Operation.Description = descriptionAttribute.Description;
            }
            else if (metadata is EndpointNameAttribute nameAttribute)
            {
                context.OperationDescription.Operation.OperationId = nameAttribute.EndpointName;
            }
        }

        return true;
    }
}

Can of course expand on this, I only added what I needed myself

BrunoBeraud commented 4 months ago

The summary annotations work when you use the WithOpenApi extension method, as documented here: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/minimal-apis/openapi?view=aspnetcore-8.0#add-endpoint-summary-or-description But the WithSumary() extension method does not work