21

I have a small project in .NET 6 that contains minimal APIs like that one

app.MapGet("/clients",
     async (IClientRepository repo) =>
     {
          var results = await repo.GetClientsAsync();
          return mapper.Map<IEnumerable<ClientModel>>(results);
     });

In the SwaggerUI I can use this API but I can't find a way to add description to it (although in the project settings I check for creating an API XML documentation).

enter image description here

How can I add the XML comment?

1

5 Answers 5

34

Currently support for Open API docs for minimal APIs is quite minimal and does not allow adding descriptions/summaries as far as I can see. There is a feature planned for .NET 7 to add descriptions. Also soon Swashbuckle should consider EndpointMetadata for annotations.

Also related issue.

UPDATE

With latest updates to Swashbuckle nuget packages and Swashbuckle.AspNetCore.Annotations you can add description to the endpoints:

builder.Services.AddSwaggerGen(opts => opts.EnableAnnotations());

app.MapGet("/weatherforecast", () =>
{
    // Implementation
})
.WithMetadata(new SwaggerOperationAttribute(summary: "Summary", description: "Descritption Test"));

// Or

app.MapGet("/weatherforecast1", [SwaggerOperation(summary: "Summary1", description: "Descritption Test1")] () =>
{
    // Implementation
});

UPDATE 2

For .NET 7 and latest Swashbuckle.AspNetCore package WithDescription method also can be used:

builder.Services.AddSwaggerGen();
...

app.MapGet("/weatherforecast", () =>
{
    // implementation
})
.WithDescription("Some Method Description")
.WithOpenApi();

Or with EndpointDescriptionAttribute:

app.MapGet("/weatherforecast1", [EndpointDescription("Some Attribute description")] () =>
{
    // implementation
})
.WithOpenApi();
Sign up to request clarification or add additional context in comments.

6 Comments

I would like to add, that WithOpenApi method you can find in Microsoft.AspNetCore.OpenApi NuGet package.
The WithOpenApi extension method also supports setting the operation's description by passing a delegate like operation => operation.Description = "foo"; return operation;. It's a little bit more robust because you can modify the entire operation.
While some of the provided solutions work for pieces of documentation (like summary and description), I can't seem to find any information on documenting parameters. Has anyone come across the appropriate way to add documentation for the parameters?
@Xorcist AFAIK .NET 7 should support swagger documentation from xml comments - you can try it. Or try marking parameters with SwaggerParameterAttribute from Swashbuckle.AspNetCore.Annotations.
I found the route cause of the parameters not be documented (in my case). Turns out if the minimal api endpoint mapping is defined with .WithOpenApi() the parameters will not be processed, but if you take that method call off, everything works as expected.
|
18

package Swashbuckle.AspNetCore.Annotations 6.3

...
builder.Services.AddSwaggerGen(c => c.EnableAnnotations());

var app = builder.build();

app.MapGet("/clients",
    [SwaggerOperation(
        Summary = "returns clients",
        Description = "more description on get `clients`")]
    [SwaggerResponse(200, "success")]
    [SwaggerResponse(500, "some failure")]
    async (IClientRepository repo) =>
    {
        var results = await repo.GetClientsAsync();
        return mapper.Map<IEnumerable<ClientModel>>(results);
    }).WithTags("Clients");

more examples here https://github.com/domaindrivendev/Swashbuckle.AspNetCore#enrich-operation-metadata

Comments

15

1. Install package

dotnet add package Swashbuckle.AspNetCore.Annotations

2. Write code

// Program.cs

builder.Services.AddSwaggerGen(x =>
{
  x.EnableAnnotations();
});

// app.MapGet("/hi", [SwaggerOperation(Summary = "summary001", Description = "description001 `adads`")] () => "Hi");

app.MapGet("/hi", () => "Hi")
  .WithMetadata(new SwaggerOperationAttribute("summary001", "description001"));

Result

enter image description here

Comments

2

You may use this guide. It worked for me using Swashbuckle. There are extension methods that come with minimal APIs. Here is how it looks:

app.MapGet(“/books”, async (BooksDB db) =>
await db.Books.ToListAsync()
)
.Produces<List<Book>>(StatusCodes.Status200OK)
.WithName(“GetAllBooks”).WithTags(“Getters”);

1 Comment

This link doesn't explain how to add a comment
2

you may use Extension Methods Which I think are more cleaner way to document API endpoints. This way you can define generic response methods for each endpoint.

For this you need to install the following packages :

Swashbuckle.AspNetCore and Swashbuckle.AspNetCore.Annotations

using Microsoft.AspNetCore.Authorization;
using Swashbuckle.AspNetCore.Annotations;


public static class MinimalAttributeExtensions
{
    public static RouteHandlerBuilder AllowAnonymous(this RouteHandlerBuilder endpoint)
    {
        endpoint.WithMetadata(new AllowAnonymousAttribute());
        return endpoint;
    }
    public static RouteHandlerBuilder Authorize(this RouteHandlerBuilder endpoint, string policy = null, string[] roles = null, params string[] schemes)
    {
        var authorizeAttribute = new AuthorizeAttribute();

        if (!string.IsNullOrEmpty(policy))
        {
            authorizeAttribute.Policy = policy;
        }

        if (roles != null && roles.Any())
        {
            authorizeAttribute.Roles = string.Join(',', roles);
        }

        if (schemes != null && schemes.Any())
        {
            authorizeAttribute.AuthenticationSchemes = string.Join(',', schemes);
        }

        endpoint.WithMetadata(authorizeAttribute);

        return endpoint;
    }
    public static RouteHandlerBuilder AddMetaData<T>(this RouteHandlerBuilder endpoint, string tag, string summary = null, string description = null)
    {
        endpoint.WithTags(tag);

        endpoint.WithMetadata(new SwaggerOperationAttribute(summary, description));

        endpoint.WithMetadata(new SwaggerResponseAttribute(200, type: typeof(T)))
                .WithMetadata(new SwaggerResponseAttribute(500, type: typeof(ErrorResponseModel)))
                .WithMetadata(new SwaggerResponseAttribute(400, type: typeof(ErrorResponseModel)))
                .WithMetadata(new SwaggerResponseAttribute(404, type: typeof(ErrorResponseModel)))
                .WithMetadata(new SwaggerResponseAttribute(422, type: typeof(ErrorResponseModel)))
                .WithMetadata(new SwaggerResponseAttribute(304, type: typeof(ErrorResponseModel)));

        return endpoint;
    }
    public static RouteHandlerBuilder AddMetaData(this RouteHandlerBuilder endpoint, string tag, string summary = null, string description = null)
    {
        endpoint.WithTags(tag);

        endpoint.WithMetadata(new SwaggerOperationAttribute(summary, description));

        endpoint.WithMetadata(new SwaggerResponseAttribute(500, type: typeof(ErrorResponseModel)))
                .WithMetadata(new SwaggerResponseAttribute(400, type: typeof(ErrorResponseModel)))
                .WithMetadata(new SwaggerResponseAttribute(404, type: typeof(ErrorResponseModel)))
                .WithMetadata(new SwaggerResponseAttribute(422, type: typeof(ErrorResponseModel)))
                .WithMetadata(new SwaggerResponseAttribute(304, type: typeof(ErrorResponseModel)));

        return endpoint;
    }
}

following is an example of how to use these extension Methods:

app.MapGet(“/books”, async (BooksDB db) =>
{
    return await db.Books.ToListAsync()
})
.Authorize(policy : "AdminOnly", roles : new string[] {1,2}, schemes: "Bearer")
.AddMetaData<List<Book>>
(
    tag : "Books",
    summary : "Get All Books",
    description : "Get All Books in List, Roles Allowed => Admin Only"
);

The .AddMetaData<T> here represents the response model for success, this will also add to the response documentation of this endpoint. In this case it is List<Book>.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.