Introdução ao Swashbuckle e ao ASP.NET Core
Observação
O Swashbuckle não está disponível no .NET 9 e versões posteriores. Encontre uma alternativa em Visão geral do suporte a OpenAPI em aplicativos da API ASP.NET Core.
O Swashbuckle tem três componentes principais:
Swashbuckle.AspNetCore.Swagger: um modelo de objeto e um middleware do Swagger para expor objetos
SwaggerDocument
como pontos de extremidade JSON.Swashbuckle.AspNetCore.SwaggerGen: um gerador do Swagger cria objetos
SwaggerDocument
diretamente de modelos, controladores e rotas. Normalmente, ela é combinada com o middleware de ponto de extremidade de Swagger para expor automaticamente o JSON do Swagger.Swashbuckle.AspNetCore.SwaggerUI: uma versão incorporada da ferramenta de interface do usuário do Swagger. Ele interpreta o JSON do Swagger a fim de criar uma experiência rica e personalizável para descrever a funcionalidade da API Web. Ele inclui os agentes de teste internos para os métodos públicos.
Instalação do pacote
O Swashbuckle pode ser adicionado com as seguintes abordagens:
Da janela Console do Gerenciador de Pacotes:
Acesse Exibição>Outras Janelas>Console do Gerenciador de Pacotes
Navegue para o diretório no qual o arquivo
.csproj
está localizadoExecute o comando a seguir:
Install-Package Swashbuckle.AspNetCore -Version 6.6.2
Da caixa de diálogo Gerenciar Pacotes NuGet:
- Clique com o botão direito do mouse no projeto em Gerenciador de Soluções>Gerenciar Pacotes NuGet
- Defina a Origem do pacote para "nuget.org"
- Verifique se a opção "Incluir pré-lançamento" está habilitada
- Insira "Swashbuckle.AspNetCore" na caixa de pesquisa
- Selecione o pacote "Swashbuckle.AspNetCore" mais recente na guia Procurar e clique em Instalar
Adicionar e configurar o middleware do Swagger
Adicione o gerador do Swagger à coleção de serviços no Program.cs
:
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
A chamada para AddEndpointsApiExplorer mostrada no exemplo anterior é necessária apenas para APIs mínimas. Para obter mais informações, confira este post do StackOverflow.
Habilite o middleware para servir o documento JSON gerado e a interface do usuário do Swagger, também em Program.cs
:
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
O código anterior adicionará o middleware do Swagger somente se o ambiente atual estiver definido como Desenvolvimento. A chamada do método UseSwaggerUI
habilita uma versão inserida da ferramenta de interface do usuário do Swagger.
Inicie o aplicativo e navegue até https://localhost:<port>/swagger/v1/swagger.json
. O documento gerado que descreve os pontos de extremidade é exibido conforme mostrado na Especificação do Openapi (openapi.json).
A interface do usuário do Swagger pode ser encontrada em https://localhost:<port>/swagger
. Explore a API por meio da interface do usuário do Swagger e incorpore-a em outros programas.
Dica
Para atender à interface do usuário do Swagger na raiz do aplicativo (https://localhost:<port>/
), defina a propriedade RoutePrefix
como uma cadeia de caracteres vazia:
if (builder.Environment.IsDevelopment())
{
app.UseSwaggerUI(options => // UseSwaggerUI is called only in Development.
{
options.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
options.RoutePrefix = string.Empty;
});
}
Se estiver usando diretórios com o IIS ou um proxy reverso, defina o ponto de extremidade do Swagger como um caminho relativo usando o prefixo ./
. Por exemplo, ./swagger/v1/swagger.json
. Usar o /swagger/v1/swagger.json
instrui o aplicativo a procurar o arquivo JSON na raiz verdadeira da URL (mais o prefixo da rota, se usado). Por exemplo, use https://localhost:<port>/<route_prefix>/swagger/v1/swagger.json
ao invés de https://localhost:<port>/<virtual_directory>/<route_prefix>/swagger/v1/swagger.json
.
Observação
Por padrão, o Swashbuckle gera e expõe o JSON do Swagger na versão 3.0 da especificação, chamada oficialmente de Especificação OpenAPI. Para dar suporte à compatibilidade com versões anteriores, você pode optar por expor o JSON no formato 2.0 como alternativa. Esse formato 2.0 é importante para integrações como o Microsoft Power Apps e o Microsoft Flow que atualmente dão suporte ao OpenAPI versão 2.0. Para aceitar o formato 2.0, defina a propriedade SerializeAsV2
em Program.cs
:
app.UseSwagger(options =>
{
options.SerializeAsV2 = true;
});
Personalizar e estender
O Swagger fornece opções para documentar o modelo de objeto e personalizar a interface do usuário para corresponder ao seu tema.
Descrição e informações da API
A ação de configuração passada para o método AddSwaggerGen
adiciona informações como o autor, a licença e a descrição.
Em Program.cs
Importe o namespace a seguir para usar a classe OpenApiInfo
:
using Microsoft.OpenApi.Models;
Usando a classe OpenApiInfo
, modifique as informações exibidas na interface do usuário:
builder.Services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v1",
Title = "ToDo API",
Description = "An ASP.NET Core Web API for managing ToDo items",
TermsOfService = new Uri("https://example.com/terms"),
Contact = new OpenApiContact
{
Name = "Example Contact",
Url = new Uri("https://example.com/contact")
},
License = new OpenApiLicense
{
Name = "Example License",
Url = new Uri("https://example.com/license")
}
});
});
A interface do usuário do Swagger exibe as informações da versão:
Comentários XML
Comentários XML podem ser habilitados com as seguintes abordagens:
- Clique com o botão direito do mouse no projeto em Gerenciador de Soluções e selecione
Edit <project_name>.csproj
. - Adicione GenerateDocumentationFile ao
.csproj
arquivo:
<PropertyGroup>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
A habilitação de comentários XML fornece informações de depuração para os membros e os tipos públicos não documentados. Os membros e tipos não documentados são indicados por mensagem de aviso. Por exemplo, a seguinte mensagem indica uma violação do código de aviso 1591:
warning CS1591: Missing XML comment for publicly visible type or member 'TodoController'
Para suprimir os avisos de todo o projeto, defina uma lista separada por ponto e vírgula dos códigos de aviso a serem ignorados no arquivo do projeto. Acrescentar os códigos de aviso ao $(NoWarn);
também aplica os valores padrão C#.
<PropertyGroup>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>
Para suprimir avisos somente para membros específicos, coloque o código nas diretivas de pré-processador #pragma warning. Essa abordagem é útil para código que não deve ser exposto por meio dos documentos da API. No exemplo a seguir, o código de aviso CS1591 é ignorado para toda a classe TodoContext
. A imposição do código de aviso é restaurada no fechamento da definição de classe. Especifique vários códigos de aviso com uma lista delimitada por vírgulas.
namespace SwashbuckleSample.Models;
#pragma warning disable CS1591
public class TodoContext : DbContext
{
public TodoContext(DbContextOptions<TodoContext> options) : base(options) { }
public DbSet<TodoItem> TodoItems => Set<TodoItem>();
}
#pragma warning restore CS1591
Configure o Swagger para usar o arquivo XML gerado com as instruções anteriores. Para sistemas operacionais Linux ou que não sejam Windows, os caminhos e nomes de arquivo podem diferenciar maiúsculas de minúsculas. Por exemplo, um arquivo TodoApi.XML
é válido no Windows, mas não no Ubuntu.
builder.Services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v1",
Title = "ToDo API",
Description = "An ASP.NET Core Web API for managing ToDo items",
TermsOfService = new Uri("https://example.com/terms"),
Contact = new OpenApiContact
{
Name = "Example Contact",
Url = new Uri("https://example.com/contact")
},
License = new OpenApiLicense
{
Name = "Example License",
Url = new Uri("https://example.com/license")
}
});
// using System.Reflection;
var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename));
});
No código anterior, a Reflexão é usada para criar um nome de arquivo XML correspondente ao do projeto de API Web. A propriedade AppContext.BaseDirectory é usada para construir um caminho para o arquivo XML. Alguns recursos do Swagger (como os esquemas de parâmetros de entrada ou dos métodos HTTP e os códigos de resposta dos respectivos atributos) funcionam sem o uso de um arquivo de documentação XML. Para a maioria dos recursos, ou seja, resumos de método e descrições dos parâmetros e códigos de resposta, é obrigatório o uso de um arquivo XML.
Adicionar comentários de barra tripla a uma ação aprimora a interface do usuário do Swagger, adicionando a descrição ao cabeçalho da seção. Adicione um elemento <summary> acima da ação Delete
:
/// <summary>
/// Deletes a specific TodoItem.
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpDelete("{id}")]
public async Task<IActionResult> Delete(long id)
{
var item = await _context.TodoItems.FindAsync(id);
if (item is null)
{
return NotFound();
}
_context.TodoItems.Remove(item);
await _context.SaveChangesAsync();
return NoContent();
}
A interface do usuário do Swagger exibe o texto interno do elemento <summary>
do código anterior:
A interface do usuário é controlada pelo esquema JSON gerado:
"delete": {
"tags": [
"Todo"
],
"summary": "Deletes a specific TodoItem.",
"parameters": [
{
"name": "id",
"in": "path",
"description": "",
"required": true,
"schema": {
"type": "integer",
"format": "int64"
}
}
],
"responses": {
"200": {
"description": "Success"
}
}
},
Adicione um elemento <remarks> na documentação do método da ação Create
. Ele complementa as informações especificadas no elemento <summary>
e fornece uma interface de usuário do Swagger mais robusta. O conteúdo do elemento <remarks>
pode consistir em texto, JSON ou XML.
/// <summary>
/// Creates a TodoItem.
/// </summary>
/// <param name="item"></param>
/// <returns>A newly created TodoItem</returns>
/// <remarks>
/// Sample request:
///
/// POST /Todo
/// {
/// "id": 1,
/// "name": "Item #1",
/// "isComplete": true
/// }
///
/// </remarks>
/// <response code="201">Returns the newly created item</response>
/// <response code="400">If the item is null</response>
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> Create(TodoItem item)
{
_context.TodoItems.Add(item);
await _context.SaveChangesAsync();
return CreatedAtAction(nameof(Get), new { id = item.Id }, item);
}
Observe os aprimoramentos da interface do usuário com esses comentários adicionais:
Anotações de dados
Marque o modelo com atributos encontrados no namespace de System.ComponentModel.DataAnnotations para ajudar a controlar os componentes de interface do usuário do Swagger.
Adicione o atributo [Required]
à propriedade Name
da classe TodoItem
:
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace SwashbuckleSample.Models;
public class TodoItem
{
public long Id { get; set; }
[Required]
public string Name { get; set; } = null!;
[DefaultValue(false)]
public bool IsComplete { get; set; }
}
A presença desse atributo altera o comportamento da interface do usuário e altera o esquema JSON subjacente:
"schemas": {
"TodoItem": {
"required": [
"name"
],
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
},
"isComplete": {
"type": "boolean",
"default": false
}
},
"additionalProperties": false
}
},
Adicione o atributo [Produces("application/json")]
ao controlador da API. Sua finalidade é declarar que as ações do controlador permitem o tipo de conteúdo de resposta application/json:
[ApiController]
[Route("api/[controller]")]
[Produces("application/json")]
public class TodoController : ControllerBase
{
A lista suspensa Tipo de Mídia seleciona esse tipo de conteúdo como o padrão para ações GET do controlador:
À medida que aumenta o uso de anotações de dados na API Web, a interface do usuário e as páginas de ajuda da API se tornam mais descritivas e úteis.
Descrever os tipos de resposta
Os desenvolvedores que usam uma API Web estão mais preocupados com o que é retornado — mais especificamente, os tipos de resposta e os códigos de erro (se eles não forem padrão). Os tipos de resposta e os códigos de erro são indicados nos comentários XML e nas anotações de dados.
A ação Create
retorna um código de status HTTP 201 em caso de sucesso. Um código de status HTTP 400 é retornado quando o corpo da solicitação postada é nulo. Sem a documentação adequada na interface do usuário do Swagger, o consumidor não tem conhecimento desses resultados esperados. Corrija esse problema adicionando as linhas realçadas no exemplo a seguir:
/// <summary>
/// Creates a TodoItem.
/// </summary>
/// <param name="item"></param>
/// <returns>A newly created TodoItem</returns>
/// <remarks>
/// Sample request:
///
/// POST /Todo
/// {
/// "id": 1,
/// "name": "Item #1",
/// "isComplete": true
/// }
///
/// </remarks>
/// <response code="201">Returns the newly created item</response>
/// <response code="400">If the item is null</response>
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> Create(TodoItem item)
{
_context.TodoItems.Add(item);
await _context.SaveChangesAsync();
return CreatedAtAction(nameof(Get), new { id = item.Id }, item);
}
A interface do usuário do Swagger agora documenta claramente os códigos de resposta HTTP esperados:
As convenções podem ser usadas como uma alternativa para decorar explicitamente as ações individuais com [ProducesResponseType]
. Para obter mais informações, confira Usar convenções da API Web.
Para dar suporte à decoração de [ProducesResponseType]
, o pacote Swashbuckle.AspNetCore.Annotations oferece extensões para habilitar e enriquecer os metadados de resposta, esquema e parâmetro.
Personalizar a interface do usuário
A interface do usuário de estoque é apresentável e funcional. No entanto, as páginas de documentação da API devem representar a sua marca ou o seu tema. Para inserir sua marca nos componentes do Swashbuckle é necessário adicionar recursos para atender aos arquivos estáticos e criar a estrutura de pasta para hospedar esses arquivos.
Habilitar o middleware de arquivos estáticos:
app.UseHttpsRedirection();
app.UseStaticFiles();
app.MapControllers();
Para injetar folhas de estilos CSS adicionais, adicione-as à pasta wwwroot do projeto e especifique o caminho relativo nas opções de middleware:
if (app.Environment.IsDevelopment())
{
app.UseSwaggerUI(options => // UseSwaggerUI is called only in Development.
{
options.InjectStylesheet("/swagger-ui/custom.css");
});
}
Recursos adicionais
Exibir ou baixar código de exemplo (como baixar)
O Swashbuckle tem três componentes principais:
Swashbuckle.AspNetCore.Swagger: um modelo de objeto e um middleware do Swagger para expor objetos
SwaggerDocument
como pontos de extremidade JSON.Swashbuckle.AspNetCore.SwaggerGen: um gerador do Swagger cria objetos
SwaggerDocument
diretamente de modelos, controladores e rotas. Normalmente, ela é combinada com o middleware de ponto de extremidade de Swagger para expor automaticamente o JSON do Swagger.Swashbuckle.AspNetCore.SwaggerUI: uma versão incorporada da ferramenta de interface do usuário do Swagger. Ele interpreta o JSON do Swagger a fim de criar uma experiência rica e personalizável para descrever a funcionalidade da API Web. Ele inclui os agentes de teste internos para os métodos públicos.
Instalação do pacote
O Swashbuckle pode ser adicionado com as seguintes abordagens:
Da janela Console do Gerenciador de Pacotes:
Acesse Exibição>Outras Janelas>Console do Gerenciador de Pacotes
Navegue para o diretório no qual o arquivo
TodoApi.csproj
está localizadoExecute o comando a seguir:
Install-Package Swashbuckle.AspNetCore -Version 5.6.3
Da caixa de diálogo Gerenciar Pacotes NuGet:
- Clique com o botão direito do mouse no projeto em Gerenciador de Soluções>Gerenciar Pacotes NuGet
- Defina a Origem do pacote para "nuget.org"
- Verifique se a opção "Incluir pré-lançamento" está habilitada
- Insira "Swashbuckle.AspNetCore" na caixa de pesquisa
- Selecione o pacote "Swashbuckle.AspNetCore" mais recente na guia Procurar e clique em Instalar
Adicionar e configurar o middleware do Swagger
Adicione o gerador do Swagger à coleção de serviços no método Startup.ConfigureServices
:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<TodoContext>(opt =>
opt.UseInMemoryDatabase("TodoList"));
services.AddControllers();
// Register the Swagger generator, defining 1 or more Swagger documents
services.AddSwaggerGen();
}
No método Startup.Configure
, habilite o middleware para atender ao documento JSON gerado e à interface do usuário do Swagger:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.)
app.UseSwaggerUI();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
Observação
O Swashbuckle depende do Microsoft.AspNetCore.Mvc.ApiExplorer do MVC para descobrir as rotas e os pontos de extremidade. Se o projeto chamar AddMvc, as rotas e os pontos de extremidade serão descobertos automaticamente. Ao chamar AddMvcCore, o método AddApiExplorer deve ser chamado explicitamente. Para obter mais informações, consulte Swashbuckle, ApiExplorer e Roteamento.
No desenvolvimento, a chamada do método UseSwaggerUI
anterior habilita uma versão inserida da ferramenta de interface do usuário do Swagger. Isso depende do Middleware de arquivo estático. Se você estiver direcionando ao .NET Framework ou ao .NET Core 1.x, adicione o pacote NuGet Microsoft.AspNetCore.StaticFiles ao projeto.
Inicie o aplicativo e navegue até http://localhost:<port>/swagger/v1/swagger.json
. O documento gerado que descreve os pontos de extremidade é exibido conforme mostrado na Especificação do Openapi (openapi.json).
A interface do usuário do Swagger pode ser encontrada em http://localhost:<port>/swagger
. Explore a API por meio da interface do usuário do Swagger e incorpore-a em outros programas.
Dica
Para atender à interface do usuário do Swagger na raiz do aplicativo (http://localhost:<port>/
), defina a propriedade RoutePrefix
como uma cadeia de caracteres vazia:
// // UseSwaggerUI Protected by if (env.IsDevelopment())
app.UseSwaggerUI(c => // UseSwaggerUI Protected by if (env.IsDevelopment())
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
c.RoutePrefix = string.Empty;
});
Se estiver usando diretórios com o IIS ou um proxy reverso, defina o ponto de extremidade do Swagger como um caminho relativo usando o prefixo ./
. Por exemplo, ./swagger/v1/swagger.json
. Usar o /swagger/v1/swagger.json
instrui o aplicativo a procurar o arquivo JSON na raiz verdadeira da URL (mais o prefixo da rota, se usado). Por exemplo, use http://localhost:<port>/<route_prefix>/swagger/v1/swagger.json
ao invés de http://localhost:<port>/<virtual_directory>/<route_prefix>/swagger/v1/swagger.json
.
Observação
Por padrão, o Swashbuckle gera e expõe o JSON do Swagger na versão 3.0 da especificação, chamada oficialmente de Especificação OpenAPI. Para dar suporte à compatibilidade com versões anteriores, você pode optar por expor o JSON no formato 2.0 como alternativa. Esse formato 2.0 é importante para integrações como o Microsoft Power Apps e o Microsoft Flow que atualmente dão suporte ao OpenAPI versão 2.0. Para aceitar o formato 2.0, defina a propriedade SerializeAsV2
em Startup.Configure
:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger(c =>
{
c.SerializeAsV2 = true;
});
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
// UseSwaggerUI is called only in Development.
app.UseSwaggerUI(c => // UseSwaggerUI Protected by if (env.IsDevelopment())
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
Personalizar e estender
O Swagger fornece opções para documentar o modelo de objeto e personalizar a interface do usuário para corresponder ao seu tema.
Na classe Startup
, adicione os seguintes namespaces:
using System;
using System.Reflection;
using System.IO;
Descrição e informações da API
A ação de configuração passada para o método AddSwaggerGen
adiciona informações como o autor, a licença e a descrição:
Na classe Startup
, importe o namespace a seguir para usar a classe OpenApiInfo
:
using Microsoft.OpenApi.Models;
Usando a classe OpenApiInfo
, modifique as informações exibidas na interface do usuário:
// Register the Swagger generator, defining 1 or more Swagger documents
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v1",
Title = "ToDo API",
Description = "A simple example ASP.NET Core Web API",
TermsOfService = new Uri("https://example.com/terms"),
Contact = new OpenApiContact
{
Name = "Shayne Boyer",
Email = string.Empty,
Url = new Uri("https://twitter.com/spboyer"),
},
License = new OpenApiLicense
{
Name = "Use under LICX",
Url = new Uri("https://example.com/license"),
}
});
});
A interface do usuário do Swagger exibe as informações da versão:
Comentários XML
Comentários XML podem ser habilitados com as seguintes abordagens:
- Clique com o botão direito do mouse no projeto em Gerenciador de Soluções e selecione
Edit <project_name>.csproj
. - Adicione manualmente as linhas realçadas ao arquivo
.csproj
:
<PropertyGroup>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>
A habilitação de comentários XML fornece informações de depuração para os membros e os tipos públicos não documentados. Os membros e tipos não documentados são indicados por mensagem de aviso. Por exemplo, a seguinte mensagem indica uma violação do código de aviso 1591:
warning CS1591: Missing XML comment for publicly visible type or member 'TodoController.GetAll()'
Para suprimir os avisos de todo o projeto, defina uma lista separada por ponto e vírgula dos códigos de aviso a serem ignorados no arquivo do projeto. Acrescentar os códigos de aviso ao $(NoWarn);
também aplica os valores padrão C#.
<PropertyGroup>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>
Para suprimir avisos somente para membros específicos, coloque o código nas diretivas de pré-processador #pragma warning. Essa abordagem é útil para código que não deve ser exposto por meio dos documentos da API. No exemplo a seguir, o código de aviso CS1591 é ignorado para toda a classe Program
. A imposição do código de aviso é restaurada no fechamento da definição de classe. Especifique vários códigos de aviso com uma lista delimitada por vírgulas.
namespace TodoApi
{
#pragma warning disable CS1591
public class Program
{
public static void Main(string[] args) =>
BuildWebHost(args).Run();
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
#pragma warning restore CS1591
}
Configure o Swagger para usar o arquivo XML gerado com as instruções anteriores. Para sistemas operacionais Linux ou que não sejam Windows, os caminhos e nomes de arquivo podem diferenciar maiúsculas de minúsculas. Por exemplo, um arquivo TodoApi.XML
é válido no Windows, mas não no Ubuntu.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<TodoContext>(opt =>
opt.UseInMemoryDatabase("TodoList"));
services.AddControllers();
// Register the Swagger generator, defining 1 or more Swagger documents
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v1",
Title = "ToDo API",
Description = "A simple example ASP.NET Core Web API",
TermsOfService = new Uri("https://example.com/terms"),
Contact = new OpenApiContact
{
Name = "Shayne Boyer",
Email = string.Empty,
Url = new Uri("https://twitter.com/spboyer"),
},
License = new OpenApiLicense
{
Name = "Use under LICX",
Url = new Uri("https://example.com/license"),
}
});
// Set the comments path for the Swagger JSON and UI.
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
});
}
No código anterior, a Reflexão é usada para criar um nome de arquivo XML correspondente ao do projeto de API Web. A propriedade AppContext.BaseDirectory é usada para construir um caminho para o arquivo XML. Alguns recursos do Swagger (como os esquemas de parâmetros de entrada ou dos métodos HTTP e os códigos de resposta dos respectivos atributos) funcionam sem o uso de um arquivo de documentação XML. Para a maioria dos recursos, ou seja, resumos de método e descrições dos parâmetros e códigos de resposta, é obrigatório o uso de um arquivo XML.
Adicionar comentários de barra tripla a uma ação aprimora a interface do usuário do Swagger, adicionando a descrição ao cabeçalho da seção. Adicione um elemento <summary> acima da ação Delete
:
/// <summary>
/// Deletes a specific TodoItem.
/// </summary>
/// <param name="id"></param>
[HttpDelete("{id}")]
public IActionResult Delete(long id)
{
var todo = _context.TodoItems.Find(id);
if (todo == null)
{
return NotFound();
}
_context.TodoItems.Remove(todo);
_context.SaveChanges();
return NoContent();
}
A interface do usuário do Swagger exibe o texto interno do elemento <summary>
do código anterior:
A interface do usuário é controlada pelo esquema JSON gerado:
"delete": {
"tags": [
"Todo"
],
"summary": "Deletes a specific TodoItem.",
"operationId": "ApiTodoByIdDelete",
"consumes": [],
"produces": [],
"parameters": [
{
"name": "id",
"in": "path",
"description": "",
"required": true,
"type": "integer",
"format": "int64"
}
],
"responses": {
"200": {
"description": "Success"
}
}
}
Adicione um elemento <remarks> na documentação do método da ação Create
. Ele complementa as informações especificadas no elemento <summary>
e fornece uma interface de usuário do Swagger mais robusta. O conteúdo do elemento <remarks>
pode consistir em texto, JSON ou XML.
/// <summary>
/// Creates a TodoItem.
/// </summary>
/// <remarks>
/// Sample request:
///
/// POST /Todo
/// {
/// "id": 1,
/// "name": "Item1",
/// "isComplete": true
/// }
///
/// </remarks>
/// <param name="item"></param>
/// <returns>A newly created TodoItem</returns>
/// <response code="201">Returns the newly created item</response>
/// <response code="400">If the item is null</response>
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<TodoItem> Create(TodoItem item)
{
_context.TodoItems.Add(item);
_context.SaveChanges();
return CreatedAtRoute("GetTodo", new { id = item.Id }, item);
}
Observe os aprimoramentos da interface do usuário com esses comentários adicionais:
Anotações de dados
Marque o modelo com atributos encontrados no namespace de System.ComponentModel.DataAnnotations para ajudar a controlar os componentes de interface do usuário do Swagger.
Adicione o atributo [Required]
à propriedade Name
da classe TodoItem
:
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace TodoApi.Models
{
public class TodoItem
{
public long Id { get; set; }
[Required]
public string Name { get; set; }
[DefaultValue(false)]
public bool IsComplete { get; set; }
}
}
A presença desse atributo altera o comportamento da interface do usuário e altera o esquema JSON subjacente:
"definitions": {
"TodoItem": {
"required": [
"name"
],
"type": "object",
"properties": {
"id": {
"format": "int64",
"type": "integer"
},
"name": {
"type": "string"
},
"isComplete": {
"default": false,
"type": "boolean"
}
}
}
},
Adicione o atributo [Produces("application/json")]
ao controlador da API. Sua finalidade é declarar que as ações do controlador permitem o tipo de conteúdo de resposta application/json:
[Produces("application/json")]
[Route("api/[controller]")]
[ApiController]
public class TodoController : ControllerBase
{
private readonly TodoContext _context;
A lista suspensa Tipo de Conteúdo de Resposta seleciona esse tipo de conteúdo como o padrão para ações GET do controlador:
À medida que aumenta o uso de anotações de dados na API Web, a interface do usuário e as páginas de ajuda da API se tornam mais descritivas e úteis.
Descrever os tipos de resposta
Os desenvolvedores que usam uma API Web estão mais preocupados com o que é retornado — mais especificamente, os tipos de resposta e os códigos de erro (se eles não forem padrão). Os tipos de resposta e os códigos de erro são indicados nos comentários XML e nas anotações de dados.
A ação Create
retorna um código de status HTTP 201 em caso de sucesso. Um código de status HTTP 400 é retornado quando o corpo da solicitação postada é nulo. Sem a documentação adequada na interface do usuário do Swagger, o consumidor não tem conhecimento desses resultados esperados. Corrija esse problema adicionando as linhas realçadas no exemplo a seguir:
/// <summary>
/// Creates a TodoItem.
/// </summary>
/// <remarks>
/// Sample request:
///
/// POST /Todo
/// {
/// "id": 1,
/// "name": "Item1",
/// "isComplete": true
/// }
///
/// </remarks>
/// <param name="item"></param>
/// <returns>A newly created TodoItem</returns>
/// <response code="201">Returns the newly created item</response>
/// <response code="400">If the item is null</response>
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<TodoItem> Create(TodoItem item)
{
_context.TodoItems.Add(item);
_context.SaveChanges();
return CreatedAtRoute("GetTodo", new { id = item.Id }, item);
}
A interface do usuário do Swagger agora documenta claramente os códigos de resposta HTTP esperados:
No ASP.NET Core 2.2 ou posterior, as convenções podem ser usadas como uma alternativa para decorar explicitamente as ações individuais com [ProducesResponseType]
. Para obter mais informações, confira Usar convenções da API Web.
Para dar suporte à decoração de [ProducesResponseType]
, o pacote Swashbuckle.AspNetCore.Annotations oferece extensões para habilitar e enriquecer os metadados de resposta, esquema e parâmetro.
Personalizar a interface do usuário
A interface do usuário de estoque é apresentável e funcional. No entanto, as páginas de documentação da API devem representar a sua marca ou o seu tema. Para inserir sua marca nos componentes do Swashbuckle é necessário adicionar recursos para atender aos arquivos estáticos e criar a estrutura de pasta para hospedar esses arquivos.
Se você estiver direcionando ao .NET Framework ou ao .NET Core 1.x, adicione o pacote do NuGet Microsoft.AspNetCore.StaticFiles ao projeto:
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.1.1" />
O pacote do NuGet anterior já estará instalado se você estiver direcionando ao .NET Core 2.x e usando o metapackage.
Habilitar o middleware de arquivos estáticos:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseStaticFiles();
if (env.IsDevelopment())
{
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c => // UseSwaggerUI Protected by if (env.IsDevelopment())
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
Para injetar folhas de estilos CSS adicionais, adicione-as à pasta wwwroot do projeto e especifique o caminho relativo nas opções de middleware:
if (env.IsDevelopment())
{
app.UseSwaggerUI(c =>
{
c.InjectStylesheet("/swagger-ui/custom.css");
}
}