Добавьте описание Swagger к минимальным API .NET6.

У меня есть небольшой проект в .NET6, который содержит минимум таких API.

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

в SwaggerUI Я могу использовать этот API, но я не могу найти способ добавить к нему описание (хотя в настройках проекта я проверяю создание XML-документации API).

Как я могу добавить комментарий XML?

5 ответов

В настоящее время поддержка документов Open API для минимальных API весьма минимальна и не позволяет добавлять описания/резюме, насколько я вижу. В .NET 7 запланирована функция добавления описаний. Также скоро Swashbuckleследует рассмотреть EndpointMetadataдля аннотаций .

Также связанная проблема .

1. Установить пакет

      dotnet add package Swashbuckle.AspNetCore.Annotations

2. Напишите код

      // 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"));

Результат

упаковка 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");

больше примеров здесь https://github.com/domaindrivendev/Swashbuckle.AspNetCore#enrich-operation-metadata

вы можете использовать методы расширения, которые я считаю более чистым способом документирования конечных точек API. Таким образом, вы можете определить общие методы ответа для каждой конечной точки.

Для этого вам необходимо установить следующие пакеты:

Swashbuckle.AspNetCore и 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;
    }
}

Ниже приведен пример использования этих методов расширения:

      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>здесь представлена ​​модель ответа для успеха, это также добавит к документации ответа этой конечной точки. В данном случае этоList<Book>.

Вы можете использовать это руководство . Это сработало для меня, используя Swashbuckle. Существуют методы расширения, которые поставляются с минимальными API. Вот как это выглядит:

      app.MapGet(“/books”, async (BooksDB db) =>
await db.Books.ToListAsync()
)
.Produces<List<Book>>(StatusCodes.Status200OK)
.WithName(“GetAllBooks”).WithTags(“Getters”);
Другие вопросы по тегам