Partilhar via


Introdução ao NSwag e ao ASP.NET Core

Por Rico Suter e Dave Brock

Visualizar ou descarregar amostra de código (como descarregar)

O NSwag oferece os seguintes recursos:

  • A capacidade de utilizar a interface Swagger e o gerador Swagger.
  • Recursos flexíveis de geração de código.

Com o NSwag, você não precisa de uma API existente — você pode usar APIs de terceiros que incorporam o Swagger e geram uma implementação de cliente. O NSwag permite que você acelere o ciclo de desenvolvimento e se adapte facilmente às alterações da API.

Instalação do pacote

Instale o NSwag para:

  • Gere a especificação Swagger para a API da Web implementada.
  • Sirva a interface do usuário do Swagger para navegar e testar a API da Web.
  • Sirva o Redoc para adicionar documentação de API para a API Web.

Para usar o middleware NSwag ASP.NET Core, instale o pacote NuGet NSwag.AspNetCore . Este pacote contém o middleware para gerar e servir a especificação Swagger, Swagger UI (v2 e v3) e ReDoc UI. O NSwag 14 suporta apenas a v3 das especificações da interface do usuário do Swagger.

Use uma das seguintes abordagens para instalar o pacote NuGet do NSwag:

  • Na janela Console do Gerenciador de Pacotes:

    • Vá para Ver>Outras Janelas>Console do Gerenciador de Pacotes

    • Navegue até o diretório no qual o arquivo NSwagSample.csproj existe

    • Execute o seguinte comando:

      Install-Package NSwag.AspNetCore
      
  • Na caixa de diálogo Gerir Pacotes NuGet:

    • Clique com o botão direito do mouse no projeto no Gerenciador de Soluções >Gerenciar Pacotes NuGet
    • Defina o de origem do pacote como "nuget.org"
    • Digite "NSwag.AspNetCore" na caixa de pesquisa
    • Selecione o pacote "NSwag.AspNetCore" na guia Procurar e clique em Instalar

Adicionar e configurar middleware Swagger

Adicione e configure o Swagger em seu aplicativo ASP.NET Core executando as seguintes etapas:

  • Adicione o gerador OpenApi à coleção de serviços em Program.cs:
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();
builder.Services.AddOpenApiDocument();
  • Ative o middleware para servir a especificação OpenApi gerada, assim como as interfaces Swagger e Redoc, também em Program.cs:
if (app.Environment.IsDevelopment())
{
    // Add OpenAPI 3.0 document serving middleware
    // Available at: http://localhost:<port>/swagger/v1/swagger.json
    app.UseOpenApi();

    // Add web UIs to interact with the document
    // Available at: http://localhost:<port>/swagger
    app.UseSwaggerUi(); // UseSwaggerUI Protected by if (env.IsDevelopment())
}
  • Iniciar a aplicação. Navegue para:
    • http://localhost:<port>/swagger para exibir a interface do Swagger.
    • http://localhost:<port>/swagger/v1/swagger.json para visualizar a especificação Swagger.

Geração de código

Você pode aproveitar os recursos de geração de código do NSwag escolhendo uma das seguintes opções:

Gerar código com NSwagStudio

  • Instale o NSwagStudio seguindo as instruções no repositório GitHub do NSwagStudio. Na página de lançamento do NSwag, você pode baixar uma versão xcopy que pode ser iniciada sem privilégios de instalação e administração.
  • Inicie o NSwagStudio e insira o URL do ficheiro na caixa de texto swagger.json. Por exemplo, http://localhost:5232/swagger/v1/swagger.json.
  • Clique no botão Criar cópia local para gerar uma representação JSON da sua especificação Swagger.

O NSwag Studio importa a especificação e exporta um CSharp Client.

  • Na área Saídas , clique na caixa de seleção CSharp Client . Dependendo do seu projeto, você também pode escolher TypeScript Client ou CSharp Web API Controller. Se você selecionar CSharp Web API Controller, uma especificação de serviço recriará o serviço, servindo como uma geração reversa.
  • Clique em Gerar saídas para produzir uma implementação completa do cliente C# do projeto TodoApi.NSwag . Para ver o código do cliente gerado, clique na guia CSharp Client :
namespace MyNamespace
{
    using System = global::System;

    [System.CodeDom.Compiler.GeneratedCode("NSwag", "14.0.1.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")]
    public partial class TodoClient
    {
    #pragma warning disable 8618 // Set by constructor via BaseUrl property
        private string _baseUrl;
    #pragma warning restore 8618 // Set by constructor via BaseUrl property
        private System.Net.Http.HttpClient _httpClient;
        private static System.Lazy<Newtonsoft.Json.JsonSerializerSettings> _settings = new System.Lazy<Newtonsoft.Json.JsonSerializerSettings>(CreateSerializerSettings, true);

        public TodoClient(System.Net.Http.HttpClient httpClient)
        {
            BaseUrl = "http://localhost:5232";
            _httpClient = httpClient;
        }

        private static Newtonsoft.Json.JsonSerializerSettings CreateSerializerSettings()
        {
            var settings = new Newtonsoft.Json.JsonSerializerSettings();
            UpdateJsonSerializerSettings(settings);
            return settings;
        }

        public string BaseUrl
        {
            get { return _baseUrl; }
            set
            {
                _baseUrl = value;
                if (!string.IsNullOrEmpty(_baseUrl) && !_baseUrl.EndsWith("/"))
                    _baseUrl += '/';
            }
        }
        // code omitted for brevity

Tip

O código do cliente C# é gerado com base em seleções na guia Configurações . Modifique as configurações para executar tarefas como renomeação de namespace padrão e geração de método síncrono.

  • Copie o código C# gerado em um arquivo no projeto cliente que consumirá a API.
  • Comece a consumir a API da Web:
var todoClient = new TodoClient(new HttpClient());

// Gets all to-dos from the API
var allTodos = await todoClient.GetAsync();

// Create a new TodoItem, and save it via the API.
await todoClient.CreateAsync(new TodoItem());

// Get a single to-do by ID
var foundTodo = await todoClient.GetByIdAsync(1);

Personalizar a documentação da API

OpenApi fornece opções para documentar o modelo de objeto para facilitar o consumo da API da Web.

Informações e descrição da API

No Program.cs, atualize AddOpenApiDocument para configurar as informações do documento da API da Web e incluir mais informações, como autor, licença e descrição. Importe o NSwag namespace primeiro para usar as OpenApi classes.

using NSwag;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenApiDocument(options => {
     options.PostProcess = document =>
     {
         document.Info = new OpenApiInfo
         {
             Version = "v1",
             Title = "ToDo API",
             Description = "An ASP.NET Core Web API for managing ToDo items",
             TermsOfService = "https://example.com/terms",
             Contact = new OpenApiContact
             {
                 Name = "Example Contact",
                 Url = "https://example.com/contact"
             },
             License = new OpenApiLicense
             {
                 Name = "Example License",
                 Url = "https://example.com/license"
             }
         };
     };
});

A interface do usuário do Swagger exibe as informações da versão:

Interface do usuário do Swagger com informações de versão.

Comentários XML

Para habilitar comentários XML, execute as seguintes etapas:

  • 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>
</PropertyGroup>

Ao ativar comentários XML, são fornecidas informações de depuração para tipos e membros públicos não documentados. Tipos e membros não documentados são indicados pela 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 'TodoContext'

Para suprimir avisos em todo o projeto, defina uma lista delimitada por ponto-e-vírgula de códigos de aviso a serem ignorados no arquivo de projeto. Anexar os códigos de aviso a $(NoWarn); também aplica os valores padrão de C# .

<PropertyGroup>
  <GenerateDocumentationFile>true</GenerateDocumentationFile>
  <NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>

Para suprimir avisos apenas para membros específicos, coloque o código em 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 aplicação do código de aviso é restaurada na conclusão da definição da classe. Especifique vários códigos de aviso com uma lista delimitada por vírgula.

namespace NSwagSample.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

Anotações de dados

Marque o modelo com atributos, encontrados no namespace System.ComponentModel.DataAnnotations, para ajudar a conduzir os componentes da interface do usuário do Swagger.

Adicione o atributo [Required] à propriedade Name da classe TodoItem:

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace NSwagSample.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:

"TodoItem": {
  "type": "object",
  "additionalProperties": false,
  "required": [
    "name"
  ],
  "properties": {
    "id": {
      "type": "integer",
      "format": "int64"
    },
    "name": {
      "type": "string",
      "minLength": 1
    },
    "isComplete": {
      "type": "boolean",
      "default": false
    }
  }
}

À medida que o uso de anotações de dados na API da Web aumenta, 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 consomem uma API da Web estão mais preocupados com o que é retornado — especificamente tipos de resposta e códigos de erro (se não padrão). Os tipos de resposta e códigos de erro são indicados nos comentários XML e anotações de dados.

A ação Create retorna um código de status HTTP 201 com êxito. Um código de status HTTP 400 é retornado quando o corpo da solicitação postada é null. 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 (e os comentários XML também são exibidos):

UI do Swagger mostrando a descrição da classe de resposta POST 'Retorna o item recém-criado da lista de tarefas (Todo)' e '400 - Se o item for nulo' para o código de estado e motivo nas Mensagens de Resposta.

As convenções podem ser usadas como uma alternativa para decorar explicitamente ações individuais com [ProducesResponseType]. Para obter mais informações, consulte Usar convenções de API da Web.

Redoc

O Redoc é uma alternativa à interface do usuário do Swagger. É semelhante porque também fornece uma página de documentação para a API da Web usando a especificação OpenAPI. A diferença é que a interface do usuário do Redoc é mais focada na documentação e não fornece uma interface do usuário interativa para testar a API.

Para habilitar o Redoc, adicione seu middleware a Program.cs:

if (app.Environment.IsDevelopment())
{
    // Add OpenAPI 3.0 document serving middleware
    // Available at: http://localhost:<port>/swagger/v1/swagger.json
    app.UseOpenApi();

    // Add web UIs to interact with the document
    // Available at: http://localhost:<port>/swagger
    app.UseSwaggerUi(); // UseSwaggerUI is called only in Development.
    
    // Add ReDoc UI to interact with the document
    // Available at: http://localhost:<port>/redoc
    app.UseReDoc(options =>
    {
        options.Path = "/redoc";
    });
}

Execute a aplicação e navegue até http://localhost:<port>/redoc para exibir a interface do utilizador do Redoc.

Documentação Redoc para a API de exemplo.

Por Rico Suter e Dave Brock

Visualizar ou descarregar amostra de código (como descarregar)

O NSwag oferece os seguintes recursos:

  • A capacidade de utilizar a interface Swagger e o gerador Swagger.
  • Recursos flexíveis de geração de código.

Com o NSwag, você não precisa de uma API existente — você pode usar APIs de terceiros que incorporam o Swagger e geram uma implementação de cliente. O NSwag permite que você acelere o ciclo de desenvolvimento e se adapte facilmente às alterações da API.

Registrar o middleware do NSwag

Registre o middleware do NSwag para:

  • Gere a especificação Swagger para a API da Web implementada.
  • Sirva a interface do usuário do Swagger para navegar e testar a API da Web.

Para usar o middleware NSwag ASP.NET Core, instale o pacote NuGet NSwag.AspNetCore . Este pacote contém o middleware para gerar e servir a especificação Swagger, Swagger UI (v2 e v3) e ReDoc UI.

Use uma das seguintes abordagens para instalar o pacote NuGet do NSwag:

  • Na janela Console do Gerenciador de Pacotes:

    • Vá para Ver>Outras Janelas>Console do Gerenciador de Pacotes

    • Navegue até o diretório no qual o arquivo TodoApi.csproj existe

    • Execute o seguinte comando:

      Install-Package NSwag.AspNetCore
      
  • Na caixa de diálogo Gerir Pacotes NuGet:

    • Clique com o botão direito do mouse no projeto no Gerenciador de Soluções >Gerenciar Pacotes NuGet
    • Defina o de origem do pacote como "nuget.org"
    • Digite "NSwag.AspNetCore" na caixa de pesquisa
    • Selecione o pacote "NSwag.AspNetCore" na guia Procurar e clique em Instalar

Adicionar e configurar middleware Swagger

Adicione e configure o Swagger em seu aplicativo ASP.NET Core executando as seguintes etapas:

  • No método Startup.ConfigureServices, registe os serviços Swagger necessários:
public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<TodoContext>(opt =>
        opt.UseInMemoryDatabase("TodoList"));
    services.AddMvc();

    // Register the Swagger services
    services.AddSwaggerDocument();
}
  • No método Startup.Configure, habilite o middleware para servir a especificação Swagger gerada e o Swagger UI:
public void Configure(IApplicationBuilder app)
{
    app.UseStaticFiles();

    // Register the Swagger generator and the Swagger UI middlewares
    app.UseOpenApi();
    app.UseOpenApi();
    if (env.IsDevelopment())
    {
        app.UseSwaggerUi3();
    }
    app.UseMvc();
}
  • Iniciar a aplicação. Navegue para:
    • http://localhost:<port>/swagger para exibir a interface do Swagger.
    • http://localhost:<port>/swagger/v1/swagger.json para visualizar a especificação Swagger.

Geração de código

Você pode aproveitar os recursos de geração de código do NSwag escolhendo uma das seguintes opções:

Gerar código com NSwagStudio

  • Instale o NSwagStudio seguindo as instruções no repositório GitHub do NSwagStudio. Na página de lançamento do NSwag, você pode baixar uma versão xcopy que pode ser iniciada sem privilégios de instalação e administração.

  • Inicie o NSwagStudio e insira o URL do ficheiro na caixa de texto swagger.json. Por exemplo, http://localhost:44354/swagger/v1/swagger.json.

  • Clique no botão Criar cópia local para gerar uma representação JSON da sua especificação Swagger.

    Criar cópia local da especificação Swagger

  • Na área Saídas , clique na caixa de seleção CSharp Client . Dependendo do seu projeto, você também pode escolher TypeScript Client ou CSharp Web API Controller. Se você selecionar CSharp Web API Controller, uma especificação de serviço recriará o serviço, servindo como uma geração reversa.

  • Clique em Gerar saídas para produzir uma implementação completa do cliente C# do projeto TodoApi.NSwag . Para ver o código do cliente gerado, clique na guia CSharp Client :

//----------------------
// <auto-generated>
//     Generated using the NSwag toolchain v12.0.9.0 (NJsonSchema v9.13.10.0 (Newtonsoft.Json v11.0.0.0)) (http://NSwag.org)
// </auto-generated>
//----------------------

namespace MyNamespace
{
    #pragma warning disable

    [System.CodeDom.Compiler.GeneratedCode("NSwag", "12.0.9.0 (NJsonSchema v9.13.10.0 (Newtonsoft.Json v11.0.0.0))")]
    public partial class TodoClient
    {
        private string _baseUrl = "https://localhost:44354";
        private System.Net.Http.HttpClient _httpClient;
        private System.Lazy<Newtonsoft.Json.JsonSerializerSettings> _settings;

        public TodoClient(System.Net.Http.HttpClient httpClient)
        {
            _httpClient = httpClient;
            _settings = new System.Lazy<Newtonsoft.Json.JsonSerializerSettings>(() =>
            {
                var settings = new Newtonsoft.Json.JsonSerializerSettings();
                UpdateJsonSerializerSettings(settings);
                return settings;
            });
        }

        public string BaseUrl
        {
            get { return _baseUrl; }
            set { _baseUrl = value; }
        }

        // code omitted for brevity

Tip

O código do cliente C# é gerado com base em seleções na guia Configurações . Modifique as configurações para executar tarefas como renomeação de namespace padrão e geração de método síncrono.

  • Copie o código C# gerado em um arquivo no projeto cliente que consumirá a API.
  • Comece a consumir a API da Web:
 var todoClient = new TodoClient();

// Gets all to-dos from the API
 var allTodos = await todoClient.GetAllAsync();

 // Create a new TodoItem, and save it via the API.
var createdTodo = await todoClient.CreateAsync(new TodoItem());

// Get a single to-do by ID
var foundTodo = await todoClient.GetByIdAsync(1);

Personalizar a documentação da API

O Swagger fornece opções para documentar o modelo de objeto para facilitar o consumo da API da Web.

Informações e descrição da API

Startup.ConfigureServices No método, uma ação de configuração passada para o AddSwaggerDocument método adiciona informações como autor, licença e descrição:

services.AddSwaggerDocument(config =>
{
    config.PostProcess = document =>
    {
        document.Info.Version = "v1";
        document.Info.Title = "ToDo API";
        document.Info.Description = "A simple ASP.NET Core web API";
        document.Info.TermsOfService = "None";
        document.Info.Contact = new NSwag.OpenApiContact
        {
            Name = "Shayne Boyer",
            Email = string.Empty,
            Url = "https://twitter.com/spboyer"
        };
        document.Info.License = new NSwag.OpenApiLicense
        {
            Name = "Use under LICX",
            Url = "https://example.com/license"
        };
    };
});

A interface do usuário do Swagger exibe as informações da versão:

Interface do usuário do Swagger com informações de versão

Comentários XML

Para habilitar comentários XML, execute as seguintes etapas:

  • 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>

Anotações de dados

Como o NSwag usa Reflection, e o tipo de retorno recomendado para ações de API da Web é ActionResult<T>, ele só pode inferir o tipo de retorno definido por T. Não é possível inferir automaticamente outros tipos de retorno possíveis.

Considere o seguinte exemplo:

[HttpPost]
public ActionResult<TodoItem> Create(TodoItem item)
{
    _context.TodoItems.Add(item);
    _context.SaveChanges();

    return CreatedAtRoute("GetTodo", new { id = item.Id }, item);
}

A ação anterior retorna ActionResult<T>. Dentro da ação, está voltando CreatedAtRoute. Como o controlador tem o [ApiController] atributo, uma BadRequest resposta também é possível. Para obter mais informações, consulte Respostas HTTP 400 automáticas. Use anotações de dados para informar aos clientes quais códigos de status HTTP essa ação é conhecida por retornar. Marque a ação com os seguintes atributos:

[ProducesResponseType(StatusCodes.Status201Created)]     // Created
[ProducesResponseType(StatusCodes.Status400BadRequest)]  // BadRequest

No ASP.NET Core 2.2 ou posterior, pode usar convenções em vez de decorar explicitamente ações individuais com [ProducesResponseType]. Para obter mais informações, consulte Usar convenções de API da Web.

O gerador Swagger agora pode descrever com precisão essa ação, e os clientes gerados sabem exatamente o que recebem ao chamar o endpoint. Como recomendação, marque todas as ações com esses atributos.

Para obter diretrizes sobre quais respostas HTTP suas ações de API devem retornar, consulte RFC 9110: Semântica HTTP (Seção 9.3. Definições de Método).