Partilhar via


Gerar documentos OpenAPI

O pacote Microsoft.AspNetCore.OpenApi fornece suporte interno para a geração de documentos OpenAPI no ASP.NET Core. O pacote fornece os seguintes recursos:

  • Suporte para geração de documentos OpenAPI em tempo de execução e acesso a esses documentos por meio de um ponto de extremidade no aplicativo.
  • Suporte para APIs "transformadoras" que permitem modificar o documento gerado.
  • Suporte para gerar vários documentos OpenAPI a partir de um único aplicativo.
  • Aproveita o suporte ao esquema JSON fornecido por System.Text.Json.
  • É compatível com o AoT nativo.

Instalação do pacote

Instalar o pacote Microsoft.AspNetCore.OpenApi:

Execute o seguinte comando no Console do Gerenciador de Pacotes:

Install-Package Microsoft.AspNetCore.OpenApi -IncludePrerelease

Configurar a geração de documentos OpenAPI

O seguinte código:

  • Adiciona serviços OpenAPI.
  • Habilita o ponto de extremidade para exibir o documento OpenAPI no formato JSON.
var builder = WebApplication.CreateBuilder();

builder.Services.AddOpenApi();

var app = builder.Build();

app.MapOpenApi();

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

app.Run();

Inicie o aplicativo e navegue até https://localhost:<port>/openapi/v1.json para exibir o documento OpenAPI gerado.

Opções para personalizar a geração de documentos OpenAPI

As seções a seguir demonstram como personalizar a geração de documentos OpenAPI.

Personalizar o nome do documento OpenAPI

Cada documento OpenAPI em um aplicativo tem um nome exclusivo. O nome do documento padrão registrado é v1.

builder.Services.AddOpenApi(); // Document name is v1

Para modificar o nome do documento, passe o nome como um parâmetro para a chamada AddOpenApi.

builder.Services.AddOpenApi("internal"); // Document name is internal

O nome do documento aparece em vários locais na implementação do OpenAPI.

Ao buscar o documento OpenAPI gerado, o nome do documento é fornecido como o argumento de parâmetro documentName na solicitação. As solicitações a seguir resolvem os documentos v1 e internal.

GET http://localhost:5000/openapi/v1.json
GET http://localhost:5000/openapi/internal.json

Personalizar a versão do OpenAPI de um documento gerado

Por padrão, a geração de documentos OpenAPI cria um documento compatível com a v3.0 da especificação OpenAPI. O código a seguir demonstra como modificar a versão padrão do documento OpenAPI:

builder.Services.AddOpenApi(options =>
{
    options.OpenApiVersion = OpenApiSpecVersion.OpenApi2_0;
});

Personalizar a rota do ponto de extremidade OpenAPI

Por padrão, o ponto de extremidade OpenAPI registrado por meio de uma chamada para MapOpenApi expõe o documento no ponto de extremidade /openapi/{documentName}.json. O código a seguir demonstra como personalizar a rota na qual o documento OpenAPI está registrado:

app.MapOpenApi("/openapi/{documentName}/openapi.json");

É possível, mas não recomendado, remover o parâmetro de rota documentName da rota do ponto de extremidade. Quando o parâmetro de rota documentName é removido da rota do ponto de extremidade, a estrutura tenta resolver o nome do documento a partir do parâmetro de consulta. Não fornecer o documentName na rota ou na consulta pode resultar em um comportamento inesperado.

Personalizar o ponto de extremidade OpenAPI

Como o documento OpenAPI é servido por meio de um ponto de extremidade do manipulador de rota, qualquer personalização disponível para ponto de extremidade mínimos padrão estará disponível para o ponto de extremidade OpenAPI.

Limitar o acesso a documentos OpenAPI a usuários autorizados

O ponto de extremidade OpenAPI não permite nenhuma verificação de autorização por padrão. No entanto, as verificações de autorização podem ser aplicadas ao documento OpenAPI. No código a seguir, o acesso ao documento OpenAPI é limitado a quem possui a função tester:

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.OpenApi;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;

var builder = WebApplication.CreateBuilder();

builder.Services.AddAuthentication().AddJwtBearer();
builder.Services.AddAuthorization(o =>
{
    o.AddPolicy("ApiTesterPolicy", b => b.RequireRole("tester"));
});
builder.Services.AddOpenApi();

var app = builder.Build();

app.MapOpenApi()
    .RequireAuthorization("ApiTesterPolicy");

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

app.Run();

Documento OpenAPI gerado pelo cache

O documento OpenAPI é gerado novamente sempre que uma solicitação ao ponto de extremidade OpenAPI é enviada. A regeneração permite que os transformadores incorporem o estado dinâmico do aplicativo em sua operação. Por exemplo, regenerar uma solicitação com detalhes do contexto HTTP. Quando aplicável, o documento OpenAPI pode ser armazenado em cache para evitar a execução do pipeline de geração de documentos em cada solicitação HTTP.

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.OpenApi;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;

var builder = WebApplication.CreateBuilder();

builder.Services.AddOutputCache(options =>
{
    options.AddBasePolicy(policy => policy.Expire(TimeSpan.FromMinutes(10)));
});
builder.Services.AddOpenApi();

var app = builder.Build();

app.UseOutputCache();

app.MapOpenApi()
    .CacheOutput();

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

app.Run();

Gerar documentos OpenAPI em tempo de compilação

Em aplicativos da Web típicos, os documentos OpenAPI são gerados em tempo de execução e servidos por meio de uma solicitação HTTP para o servidor de aplicativos.

Em alguns cenários, é útil gerar o documento OpenAPI durante a etapa de build do aplicativo. Esses cenários incluem:

  • Gerar documentação OpenAPI confirmada no controle do código-fonte.
  • Gerar documentação do OpenAPI que é usada para testes de integração baseados em especificações.
  • Gerar documentação OpenAPI que é servida estaticamente a partir do servidor web.

Para adicionar suporte para a geração de documentos OpenAPI no momento da compilação, instale o pacote Microsoft.Extensions.ApiDescription.Server:

Execute o seguinte comando no Console do Gerenciador de Pacotes:

Install-Package Microsoft.Extensions.ApiDescription.Server -IncludePrerelease

Após a instalação, esse pacote gerará automaticamente o(s) documento(s) da API aberta associado(s) ao aplicativo durante a compilação e os preencherá no diretório de saída do aplicativo.

$ dotnet build
$ cat bin/Debug/net9.0/{ProjectName}.json

Personalizando a geração de documentos em tempo de compilação

Modificando o diretório de saída do arquivo Open API gerado

Por padrão, o documento OpenAPI gerado será emitido para o diretório de saída do aplicativo. Para modificar o local do arquivo emitido, defina o caminho de destino na OpenApiDocumentsDirectory propriedade.

<PropertyGroup>
  <OpenApiDocumentsDirectory>./</OpenApiDocumentsDirectory>
</PropertyGroup>

O valor de é resolvido em relação ao arquivo de OpenApiDocumentsDirectory projeto. O uso do ./ valor acima emitirá o documento OpenAPI no mesmo diretório que o arquivo de projeto.

Modificando o nome do arquivo de saída

Por padrão, o documento OpenAPI gerado terá o mesmo nome que o arquivo de projeto do aplicativo. Para modificar o nome do arquivo emitido, defina o --file-name OpenApiGenerateDocumentsOptions argumento na propriedade.

<PropertyGroup>
  <OpenApiGenerateDocumentsOptions>--file-name my-open-api</OpenApiGenerateDocumentsOptions>
</PropertyGroup>

Selecionando o documento OpenAPI a ser gerado

Alguns aplicativos podem ser configurados para emitir vários documentos OpenAPI, para várias versões de uma API ou para distinguir entre APIs públicas e internas. Por padrão, o gerador de documentos em tempo de compilação emitirá arquivos para todos os documentos configurados em um aplicativo. Para emitir apenas um único nome de documento, defina o --document-name OpenApiGenerateDocumentsOptions argumento na propriedade.

<PropertyGroup>
  <OpenApiGenerateDocumentsOptions>--document-name v2</OpenApiGenerateDocumentsOptions>
</PropertyGroup>

Personalizando o comportamento de tempo de execução durante a geração de documentos de tempo de compilação

Nos bastidores, a geração de documentos OpenAPI em tempo de compilação funciona iniciando o ponto de entrada do aplicativo com uma implementação de servidor inerte. Este é um requisito para produzir documentos OpenAPI precisos, pois todas as informações no documento OpenAPI não podem ser analisadas estaticamente. Como o ponto de entrada do aplicativo é invocado, qualquer lógica na inicialização dos aplicativos será invocada. Isso inclui código que injeta serviços no contêiner de DI ou lê da configuração. Em alguns cenários, é necessário restringir os caminhos de código que serão executados quando o ponto de entrada do aplicativo estiver sendo invocado da geração de documentos em tempo de build. Esses cenários incluem:

  • Não lendo determinadas strings de configuração.
  • Não registrar serviços relacionados ao banco de dados.

Para impedir que esses caminhos de código sejam invocados pelo pipeline de geração em tempo de build, eles podem ser condicionados por trás de uma verificação do assembly de entrada da seguinte forma:

using System.Reflection;

var builder = WebApplication.CreateBuilder();

if (Assembly.GetEntryAssembly()?.GetName().Name != "GetDocument.Insider")
{
  builder.Services.AddDefaults();
}

As APIs mínimas fornecem suporte interno para gerar informações sobre pontos de extremidade em um aplicativo por meio do pacote Microsoft.AspNetCore.OpenApi. Expor a definição do OpenAPI gerada por meio de uma interface do usuário visual requer um pacote de terceiros. Para obter informações sobre o suporte para OpenAPI em APIs baseadas em controlador, consulte a versão .NET 9 deste artigo.

O código a seguir é gerado pelo modelo de API Web mínima do ASP.NET Core e usa o OpenAPI:

using Microsoft.AspNetCore.OpenApi;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

var summaries = new[]
{
    "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};

app.MapGet("/weatherforecast", () =>
{
    var forecast = Enumerable.Range(1, 5).Select(index =>
        new WeatherForecast
        (
            DateTime.Now.AddDays(index),
            Random.Shared.Next(-20, 55),
            summaries[Random.Shared.Next(summaries.Length)]
        ))
        .ToArray();
    return forecast;
})
.WithName("GetWeatherForecast")
.WithOpenApi();

app.Run();

internal record WeatherForecast(DateTime Date, int TemperatureC, string? Summary)
{
    public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}

No código realçado anterior:

  • O Microsoft.AspNetCore.OpenApi é explicado na próxima seção.
  • AddEndpointsApiExplorer: configura o aplicativo para usar a API Explorer para descobrir e descrever pontos de extremidade com anotações padrão. O WithOpenApisubstitui as anotações padrão e correspondentes geradas pela API Explorer com aquelas produzidas no pacote Microsoft.AspNetCore.OpenApi.
  • O UseSwaggeradiciona o middleware Swagger.
  • “UseSwaggerUI” permite uma versão incorporada da ferramenta Swagger UI.
  • WithName: o IEndpointNameMetadata no ponto de extremidade é usado para geração de links e é tratado como a ID da operação na especificação do OpenAPI do ponto de extremidade fornecida.
  • O WithOpenApi é explicado posteriormente neste artigo.

Pacote NuGet Microsoft.AspNetCore.OpenApi

O ASP.NET Core fornece o pacote Microsoft.AspNetCore.OpenApi para interagir com as especificações do OpenAPI para pontos de extremidade. O pacote atua como um link entre os modelos do OpenAPI definidos no pacote Microsoft.AspNetCore.OpenApi e os pontos de extremidade definidos em APIs Mínimas. O pacote fornece uma API que examina parâmetros, respostas e metadados de um ponto de extremidade para construir um tipo de anotação do OpenAPI usado para descrever um ponto de extremidade.

O Microsoft.AspNetCore.OpenApi é adicionado como um PackageReference a um arquivo de projeto:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net7.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>    
    <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.*-*" />
    <PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
  </ItemGroup>

</Project>

Ao usar Swashbuckle.AspNetCore com Microsoft.AspNetCore.OpenApi, a versão 6.4.0 do Swashbuckle.AspNetCore ou posterior deve ser usada. A versão 1.4.3 do Microsoft.OpenApi ou posterior deve ser usada para aproveitar os construtores de cópia nas invocações do WithOpenApi.

Adicionar anotações do OpenAPI a pontos de extremidade por meio do WithOpenApi

Chamar o WithOpenApi no ponto de extremidade complementa os metadados do ponto de extremidade. Esses metadados podem ser:

  • Consumidos em pacotes de terceiros, como Swashbuckle.AspNetCore.
  • Exibidos na interface do Swagger, no YAML ou no JSON gerado para definir a API.
app.MapPost("/todoitems/{id}", async (int id, Todo todo, TodoDb db) =>
{
    todo.Id = id;
    db.Todos.Add(todo);
    await db.SaveChangesAsync();

    return Results.Created($"/todoitems/{todo.Id}", todo);
})
.WithOpenApi();

Modificar a anotação do OpenAPI no WithOpenApi

O método WithOpenApi aceita uma função que pode ser usada para modificar a anotação do OpenAPI. Por exemplo, no código a seguir, uma descrição é adicionada ao primeiro parâmetro do ponto de extremidade:

app.MapPost("/todo2/{id}", async (int id, Todo todo, TodoDb db) =>
{
    todo.Id = id;
    db.Todos.Add(todo);
    await db.SaveChangesAsync();

    return Results.Created($"/todoitems/{todo.Id}", todo);
})
.WithOpenApi(generatedOperation =>
{
    var parameter = generatedOperation.Parameters[0];
    parameter.Description = "The ID associated with the created Todo";
    return generatedOperation;
});

Adicionar IDs de operação ao OpenAPI

As IDs de operação são usadas para identificar exclusivamente um determinado ponto de extremidade no OpenAPI. O método de extensão WithName pode ser usado para definir a ID da operação usada para um método .

app.MapGet("/todoitems2", async (TodoDb db) =>
    await db.Todos.ToListAsync())
    .WithName("GetToDoItems");

Como alternativa, a propriedade OperationId pode ser definida diretamente na anotação do OpenAPI.

app.MapGet("/todos", async (TodoDb db) => await db.Todos.ToListAsync())
    .WithOpenApi(operation => new(operation)
    {
        OperationId = "GetTodos"
    });

Adicionar marcas à descrição do OpenAPI

O OpenAPI dá suporte ao uso de objetos de marca para categorizar operações. Normalmente, essas marcas são usadas para agrupar operações na interface do usuário do Swagger. Essas marcas podem ser adicionadas a uma operação invocando o método de extensão WithTags no ponto de extremidade com as marcas desejadas.

app.MapGet("/todoitems", async (TodoDb db) =>
    await db.Todos.ToListAsync())
    .WithTags("TodoGroup");

Como alternativa, a lista de OpenApiTags pode ser definida na anotação do OpenAPI por meio do método de extensão WithOpenApi.

app.MapGet("/todos", async (TodoDb db) => await db.Todos.ToListAsync())
    .WithOpenApi(operation => new(operation)
    {
        Tags = new List<OpenApiTag> { new() { Name = "Todos" } }
    });

Adicionar resumo ou descrição do ponto de extremidade

O resumo e a descrição do ponto de extremidade podem ser adicionados invocando o método de extensão WithOpenApi. No código a seguir, os resumos são definidos diretamente na anotação do OpenAPI.

app.MapGet("/todoitems2", async (TodoDb db) => await db.Todos.ToListAsync())
    .WithOpenApi(operation => new(operation)
    {
        Summary = "This is a summary",
        Description = "This is a description"
    });

Excluir descrição do OpenAPI

No exemplo a seguir, o ponto de extremidade /skipme é excluído da geração de uma descrição do OpenAPI:

using Microsoft.AspNetCore.OpenApi;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.MapGet("/swag", () => "Hello Swagger!")
    .WithOpenApi();
app.MapGet("/skipme", () => "Skipping Swagger.")
                    .ExcludeFromDescription();

app.Run();

Marcar uma API como obsoleta

Para marcar um ponto de extremidade como obsoleto, defina a propriedade Deprecated na anotação do OpenAPI.

app.MapGet("/todos", async (TodoDb db) => await db.Todos.ToListAsync())
    .WithOpenApi(operation => new(operation)
    {
        Deprecated = true
    });

Descrever os tipos de resposta

O OpenAPI dá suporte ao fornecimento de uma descrição das respostas retornadas de uma API. As APIs mínimas dão suporte a três estratégias para definir o tipo de resposta de um ponto de extremidade:

O método de extensão Produces pode ser usado para adicionar metadados Produces a um ponto de extremidade. Quando nenhum parâmetro é fornecido, o método de extensão preenche metadados para o tipo de destino em um código de status 200 e um tipo de conteúdo application/json.

app
    .MapGet("/todos", async (TodoDb db) => await db.Todos.ToListAsync())
    .Produces<IList<Todo>>();

Usar TypedResults na implementação do manipulador de rotas de um ponto de extremidade inclui automaticamente os metadados de tipo de resposta para o ponto de extremidade. Por exemplo, o código a seguir anota automaticamente o ponto de extremidade com uma resposta no código de status 200 com um tipo de conteúdo application/json.

app.MapGet("/todos", async (TodoDb db) =>
{
    var todos = await db.Todos.ToListAsync());
    return TypedResults.Ok(todos);
});

Definir respostas para ProblemDetails

Ao definir o tipo de resposta para pontos de extremidade que podem retornar uma resposta ProblemDetails, o método de extensão ProducesProblem, ProducesValidationProblem ou TypedResults.Problem pode ser usado para adicionar a anotação apropriada aos metadados do ponto de extremidade. Observe que os métodos de extensão ProducesProblem e ProducesValidationProblem não podem ser usados com grupos de rotas no .NET 8 e anteriores.

Quando não há anotações explícitas fornecidas por uma das estratégias acima, a estrutura tenta determinar um tipo de resposta padrão examinando a assinatura da resposta. Essa resposta padrão é preenchida sob o código de status 200 na definição do OpenAPI.

Vários tipos de resposta

Se um ponto de extremidade puder retornar diferentes tipos de resposta em cenários diferentes, você poderá fornecer metadados das seguintes maneiras:

  • Chame o método de extensão Produces várias vezes, conforme mostrado no exemplo a seguir:

    app.MapGet("/api/todoitems/{id}", async (int id, TodoDb db) =>
             await db.Todos.FindAsync(id) 
             is Todo todo
             ? Results.Ok(todo) 
             : Results.NotFound())
       .Produces<Todo>(StatusCodes.Status200OK)
       .Produces(StatusCodes.Status404NotFound);
    
  • Use Results<TResult1,TResult2,TResultN> na assinatura e TypedResults no corpo do manipulador, conforme mostrado no exemplo a seguir:

    app.MapGet("/book/{id}", Results<Ok<Book>, NotFound> (int id, List<Book> bookList) =>
    {
        return bookList.FirstOrDefault((i) => i.Id == id) is Book book
         ? TypedResults.Ok(book)
         : TypedResults.NotFound();
    });
    

    Os Results<TResult1,TResult2,TResultN> (tipos de união) declaram que um manipulador de rotas retorna vários tipos concretos de implementação IResult, e qualquer um desses tipos que implementam IEndpointMetadataProvider contribuirá para os metadados do ponto de extremidade.

    Os tipos de união implementam operadores de conversão implícitos. Esses operadores permitem que o compilador converta automaticamente os tipos especificados nos argumentos genéricos em uma instância do tipo de união. Essa funcionalidade tem o benefício adicional de verificar durante o tempo de compilação se um manipulador de rotas retorna apenas os resultados que ele declara retornar. Tentar retornar um tipo que não é declarado como um dos argumentos genéricos para Results<TResult1,TResult2,TResultN> resulta em um erro de compilação.

Descrever o corpo da solicitação e os parâmetros

Além de descrever os tipos retornados por um ponto de extremidade, o OpenAPI também dá suporte à anotação das entradas consumidas por uma API. Essas entradas se enquadram em duas categorias:

  • Parâmetros que aparecem no caminho, cadeia de caracteres de consulta, cabeçalhos ou cookies
  • Dados transmitidos como parte do corpo da solicitação

A estrutura infere os tipos de parâmetros de solicitação no caminho, na consulta e na cadeia de caracteres de cabeçalho automaticamente com base na assinatura do manipulador de rotas.

Para definir o tipo de entradas transmitidas como o corpo da solicitação, configure as propriedades usando o método de extensão Accepts para definir o tipo de objeto e o tipo de conteúdo esperados pelo manipulador de solicitação. No exemplo a seguir, o ponto de extremidade aceita um objeto Todo no corpo da solicitação com um tipo de conteúdo esperado de application/xml.

app.MapPost("/todos/{id}", (int id, Todo todo) => ...)
  .Accepts<Todo>("application/xml");

Além do método de extensão Accepts, um tipo de parâmetro pode descrever sua própria anotação implementando a interface IEndpointParameterMetadataProvider. Por exemplo, o tipo Todo a seguir adiciona uma anotação que requer um corpo da solicitação com um tipo de conteúdo application/xml.

public class Todo : IEndpointParameterMetadataProvider
{
    public static void PopulateMetadata(ParameterInfo parameter, EndpointBuilder builder)
    {
        builder.Metadata.Add(new ConsumesAttribute(typeof(Todo), isOptional: false, "application/xml"));
    }
}

Quando nenhuma anotação explícita é fornecida, a estrutura tenta determinar o tipo de solicitação padrão se houver um parâmetro do corpo da solicitação no manipulador de ponto de extremidade. A inferência usa a seguinte heurística para produzir a anotação:

  • Os parâmetros do corpo da solicitação lidos de um formulário por meio do atributo [FromForm] são descritos com o tipo de conteúdo multipart/form-data.
  • Todos os outros parâmetros do corpo da solicitação são descritos com o tipo de conteúdo application/json.
  • O corpo da solicitação será tratado como opcional se for anulável ou se a propriedade AllowEmpty estiver definida no atributo FromBody.

Suporte ao controle de versão da API

As APIs mínimas dão suporte ao controle de versão da API por meio do pacote Asp.Versioning.Http. Exemplos de configuração de controle de versão com APIs mínimas podem ser encontrados no repositório de controle de versão da API.

Código-fonte do ASP.NET Core OpenAPI no GitHub

Recursos adicionais

Um aplicativo de API mínima pode descrever a especificação do OpenAPI para manipuladores de rota usando o Swashbuckle.

Para obter informações sobre o suporte para OpenAPI em APIs baseadas em controlador, consulte a versão .NET 9 deste artigo.

O código a seguir é um aplicativo do ASP.NET Core típico com suporte ao OpenAPI:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new() { Title = builder.Environment.ApplicationName,
                               Version = "v1" });
});

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger(); // UseSwaggerUI Protected by if (env.IsDevelopment())
    app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json",
                                    $"{builder.Environment.ApplicationName} v1"));
}

app.MapGet("/swag", () => "Hello Swagger!");

app.Run();

Excluir descrição do OpenAPI

No exemplo a seguir, o ponto de extremidade /skipme é excluído da geração de uma descrição do OpenAPI:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI(); // UseSwaggerUI Protected by if (env.IsDevelopment())
}

app.MapGet("/swag", () => "Hello Swagger!");
app.MapGet("/skipme", () => "Skipping Swagger.")
                    .ExcludeFromDescription();

app.Run();

Descrever os tipos de resposta

O exemplo a seguir usa os tipos de resultados internos para personalizar a resposta:

app.MapGet("/api/todoitems/{id}", async (int id, TodoDb db) =>
         await db.Todos.FindAsync(id) 
         is Todo todo
         ? Results.Ok(todo) 
         : Results.NotFound())
   .Produces<Todo>(StatusCodes.Status200OK)
   .Produces(StatusCodes.Status404NotFound);

Adicionar IDs de operação ao OpenAPI

app.MapGet("/todoitems2", async (TodoDb db) =>
    await db.Todos.ToListAsync())
    .WithName("GetToDoItems");

Adicionar marcas à descrição do OpenAPI

O código a seguir usa uma marca de agrupamento do OpenAPI:

app.MapGet("/todoitems", async (TodoDb db) =>
    await db.Todos.ToListAsync())
    .WithTags("TodoGroup");