Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
captainsafia opened this issue Sep 27, 2022 · 11 comments
Open

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

captainsafia opened this issue Sep 27, 2022 · 11 comments

Comments

@captainsafia
Copy link
Contributor

captainsafia commented Sep 27, 2022

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 domaindrivendev/Swashbuckle.AspNetCore#2404). We also patch in the OpenApiSchema generated by Swashbuckle.AspNetCore (see domaindrivendev/Swashbuckle.AspNetCore#2441).

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

@amilcar-dev
Copy link

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
Copy link

Xyotic commented Nov 28, 2022

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

@captainsafia
Copy link
Contributor Author

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
Copy link

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
Copy link

vipwan commented Oct 13, 2023

.NET8 is comming Any new ideas?

@aunikitin
Copy link

aunikitin commented Dec 6, 2023

@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
Copy link

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
Copy link
Owner

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
Copy link
Contributor Author

@RicoSuter
There's two aspects. to this:

The WithName and WithDescription extension methods populate EndpointMetadata which is accessible via the API explorer. domaindrivendev/Swashbuckle.AspNetCore#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. domaindrivendev/Swashbuckle.AspNetCore#2404 showcases this.

@patnym
Copy link

patnym commented Feb 6, 2024

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
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants