Introducción a NSwag y ASP.NET Core
Por Christoph Nienaber, Rico Suter y Dave Brock
Vea o descargue el código de ejemplo (cómo descargarlo)
NSwag ofrece las siguientes capacidades:
- Capacidad de usar la interfaz de usuario y el generador de Swagger.
- Capacidad de generar código con flexibilidad.
Con NSwag, no es necesario que exista una API; se pueden usar API de terceros que incluyan Swagger y que generen una implementación de cliente. NSwag permite acelerar el ciclo de desarrollo y adaptarse fácilmente a los cambios de API.
Instalación del paquete
Instalar NSwag en:
- Generar la especificación de Swagger para la API web implementada.
- Proporcionar la interfaz de usuario de Swagger para examinar y probar la API web.
- Sirve a Redoc para agregar documentación de API para la API web.
Para usar NSwag con middleware de ASP.NET Core, instale el paquete NuGet NSwag.AspNetCore. Este paquete contiene el middleware para generar y proporcionar la especificación de Swagger, la interfaz de usuario de Swagger (v2 y v3) y la interfaz de usuario de ReDoc. NSwag 14 solo admite v3 de la especificación de interfaz de usuario de Swagger.
Use uno de los siguientes métodos para instalar el paquete NuGet de NSwag:
En la ventana Consola del Administrador de paquetes:
Vaya a Vista>Otras ventanas>Consola del Administrador de paquetes.
Vaya al directorio en el que está el archivo
NSwagSample.csproj
.Ejecute el siguiente comando:
Install-Package NSwag.AspNetCore
En el cuadro de diálogo Administrar paquetes NuGet:
- Haga clic con el botón derecho en el proyecto en el Explorador de soluciones>Administrar paquetes NuGet.
- Establezca el origen del paquete en "nuget.org".
- Escriba "NSwag.AspNetCore" en el cuadro de búsqueda.
- Seleccione el paquete "NSwag.AspNetCore" en la pestaña Examinar y haga clic en Instalar.
Agregar y configurar el middleware de Swagger
Para agregar y configurar Swagger en su aplicación de ASP.NET Core, realice los siguientes pasos:
- Agregue el generador de OpenApi a la colección de servicios en
Program.cs
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddOpenApiDocument();
- Habilite el middleware para atender la especificación de OpenApi generada, la interfaz de usuario de Swagger y la interfaz de usuario de Redoc, también en
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())
}
- Inicie la aplicación. Vaya a:
http://localhost:<port>/swagger
para ver la interfaz de usuario de Swagger.http://localhost:<port>/swagger/v1/swagger.json
para ver la especificación de Swagger.
Generación de código
Para aprovechar las capacidades de generación de código de NSwag, elija una de las siguientes opciones:
- NSwagStudio: aplicación de escritorio de Windows que permite generar código de cliente de API en C# o TypeScript.
- Paquetes NuGet NSwag.CodeGeneration.CSharp o NSwag.CodeGeneration.TypeScript para generar código dentro del proyecto.
- NSwag desde la línea de comandos.
- Paquete NuGet NSwag.MSBuild.
- Servicio conectado de Unchase OpenAPI (Swagger): servicio conectado de Visual Studio para generar código de cliente de API en C# o TypeScript. También genera controladores de C# para los servicios de OpenAPI con NSwag.
Generación de código con NSwagStudio
- Instale NSwagStudio siguiendo las instrucciones del repositorio de GitHub de NSwagStudio. En la página de la versión NSwag, es posible descargar una versión de xcopy que se puede iniciar sin privilegios de administrador y de instalación.
- Inicie NSwagStudio y escriba la URL del archivo
swagger.json
en el cuadro de texto URL de especificación de Swagger. Por ejemplo,http://localhost:5232/swagger/v1/swagger.json
. - Haga clic en el botón Create local Copy (Crear copia local) para generar una representación JSON de la especificación de Swagger.
- En el área Salidas, haga clic en la casilla CSharp Client (Cliente de CSharp). En función del proyecto, también puede elegir TypeScript Client (Cliente de TypeScript) o CSharp Web API Controller (Controlador de API web de CSharp). Si selecciona CSharp Web API Controller (Controlador de API web de CSharp), una especificación de servicio volverá a generar el servicio a modo de generación inversa.
- Haga clic en Generate Outputs (Generar salidas) para producir una implementación completa del cliente de C# del proyecto TodoApi.NSwag. Para ver el código de cliente generado, haga clic en la pestaña CSharp Client (Cliente de CSharp):
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
Sugerencia
El código de cliente de C# se genera en función de las selecciones en la pestaña Settings (Configuración). Modifique esta configuración para realizar tareas como cambiar el nombre del espacio de nombres predeterminado y generar un método sincrónico.
- Copie el código de C# generado en un archivo del proyecto de cliente que usará la API.
- Empiece a consumir la Web API:
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);
Personalización de la documentación de API
OpenApi proporciona opciones para documentar el modelo de objetos de cara a facilitar el consumo de Web API.
Información y descripción de la API
En Program.cs
, actualice AddOpenApiDocument
para configurar la información del documento de la API web e incluya más información, como el autor, la licencia y la descripción.
Importe primero el espacio de nombres NSwag
para usar las clases OpenApi
.
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"
}
};
};
});
La interfaz de usuario de Swagger muestra información de la versión:
comentarios XML
Para habilitar los comentarios XML, realice los siguientes pasos:
- Haga clic con el botón derecho en el Explorador de soluciones y seleccione
Edit <project_name>.csproj
. - Agregue manualmente las líneas resaltadas al archivo
.csproj
:
<PropertyGroup>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
Puede habilitar los comentarios XML para proporcionar información de depuración para miembros y tipos públicos sin documentación. Los miembros y tipos que no estén documentados se indican por medio del mensaje de advertencia. Por ejemplo, el siguiente mensaje señala una infracción con el código de advertencia 1591:
warning CS1591: Missing XML comment for publicly visible type or member 'TodoContext'
Para eliminar las advertencias a nivel de proyecto, defina una lista delimitada por punto y coma de códigos de advertencia que se deban omitir en el archivo de proyecto. Al anexar los códigos de advertencia a $(NoWarn);
, se aplican también los valores predeterminados de C#.
<PropertyGroup>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>
Para suprimir las advertencias solo para miembros específicos, incluya el código en directivas de preprocesador de advertencias #pragma. Este enfoque es útil para el código que no debe exponerse mediante los documentos de API. En el ejemplo siguiente, se omite el código de advertencia CS1591 para toda la clase TodoContext
. La ejecución del código de advertencia se restaura al cerrar la definición de clase. Especifique varios códigos de advertencia con una lista delimitada por comas.
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
Anotaciones de datos
Marque el modelo con atributos, que se encuentran en el espacio de nombres System.ComponentModel.DataAnnotations, para controlar los componentes de la interfaz de usuario de Swagger.
Agregue el atributo [Required]
a la propiedad Name
de la clase 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; }
}
La presencia de este atributo cambia el comportamiento de la interfaz de usuario y modifica el esquema JSON subyacente:
"TodoItem": {
"type": "object",
"additionalProperties": false,
"required": [
"name"
],
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string",
"minLength": 1
},
"isComplete": {
"type": "boolean",
"default": false
}
}
}
A medida que aumenta el uso de anotaciones de datos en la API web, la interfaz de usuario y las páginas de ayuda de la API pasan a ser más descriptivas y útiles.
Describir los tipos de respuesta
Lo que más preocupa a los desarrolladores que consumen una API web es lo que se devuelve; sobre todo, los tipos de respuesta y los códigos de error (si no son los habituales). Los tipos de respuesta y los códigos de error se indican en las anotaciones de datos y los comentarios XML.
La acción Create
devuelve un código de estado HTTP 201 cuando se ha ejecutado correctamente. Cuando el cuerpo de solicitud enviado es null
, se devuelve un código de estado HTTP 400. Sin la documentación correcta en la interfaz de usuario de Swagger, el consumidor no dispone de la información necesaria de estos resultados esperados. Corrija este problema agregando las líneas resaltadas en el siguiente ejemplo:
/// <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);
}
Ahora, la interfaz de usuario de Swagger documenta de forma clara los códigos de respuesta HTTP esperados (y también se muestran los comentarios XML):
Las convenciones se pueden usar como alternativa a la representación explícita de acciones individuales con [ProducesResponseType]
. Para más información, consulte Uso de convenciones de API web.
Redoc
Redoc es una alternativa a la interfaz de usuario de Swagger. Es similar porque también proporciona una página de documentación para la API web mediante la especificación OpenAPI. La diferencia es que la interfaz de usuario de Redoc se centra más en la documentación y no proporciona una interfaz de usuario interactiva para probar la API.
Para habilitar Redoc, agregue su 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";
});
}
Ejecute la aplicación y navegue a http://localhost:<port>/redoc
para ver la interfaz de usuario de Redoc:
Por Christoph Nienaber, Rico Suter y Dave Brock
Vea o descargue el código de ejemplo (cómo descargarlo)
NSwag ofrece las siguientes capacidades:
- Capacidad de usar la interfaz de usuario y el generador de Swagger.
- Capacidad de generar código con flexibilidad.
Con NSwag, no es necesario que exista una API; se pueden usar API de terceros que incluyan Swagger y que generen una implementación de cliente. NSwag permite acelerar el ciclo de desarrollo y adaptarse fácilmente a los cambios de API.
Registro del middleware de NSwag
Registre el middleware de NSwag para:
- Generar la especificación de Swagger para la API web implementada.
- Proporcionar la interfaz de usuario de Swagger para examinar y probar la API web.
Para usar NSwag con middleware de ASP.NET Core, instale el paquete NuGet NSwag.AspNetCore. Este paquete contiene el middleware para generar y proporcionar la especificación de Swagger, la interfaz de usuario de Swagger (v2 y v3) y la interfaz de usuario de ReDoc.
Use uno de los siguientes métodos para instalar el paquete NuGet de NSwag:
En la ventana Consola del Administrador de paquetes:
Vaya a Vista>Otras ventanas>Consola del Administrador de paquetes.
Vaya al directorio en el que está el archivo
TodoApi.csproj
.Ejecute el siguiente comando:
Install-Package NSwag.AspNetCore
En el cuadro de diálogo Administrar paquetes NuGet:
- Haga clic con el botón derecho en el proyecto en el Explorador de soluciones>Administrar paquetes NuGet.
- Establezca el origen del paquete en "nuget.org".
- Escriba "NSwag.AspNetCore" en el cuadro de búsqueda.
- Seleccione el paquete "NSwag.AspNetCore" en la pestaña Examinar y haga clic en Instalar.
Agregar y configurar el middleware de Swagger
Para agregar y configurar Swagger en su aplicación de ASP.NET Core, realice los siguientes pasos:
- En el método
Startup.ConfigureServices
, registre los servicios necesarios de Swagger:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<TodoContext>(opt =>
opt.UseInMemoryDatabase("TodoList"));
services.AddMvc();
// Register the Swagger services
services.AddSwaggerDocument();
}
- En el método
Startup.Configure
, habilite el middleware para servir la especificación y la interfaz de usuario de Swagger:
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();
}
- Inicie la aplicación. Vaya a:
http://localhost:<port>/swagger
para ver la interfaz de usuario de Swagger.http://localhost:<port>/swagger/v1/swagger.json
para ver la especificación de Swagger.
Generación de código
Para aprovechar las capacidades de generación de código de NSwag, elija una de las siguientes opciones:
- NSwagStudio: aplicación de escritorio de Windows que permite generar código de cliente de API en C# o TypeScript.
- Paquetes NuGet NSwag.CodeGeneration.CSharp o NSwag.CodeGeneration.TypeScript para generar código dentro del proyecto.
- NSwag desde la línea de comandos.
- Paquete NuGet NSwag.MSBuild.
- Servicio conectado de Unchase OpenAPI (Swagger): servicio conectado de Visual Studio para generar código de cliente de API en C# o TypeScript. También genera controladores de C# para los servicios de OpenAPI con NSwag.
Generación de código con NSwagStudio
Instale NSwagStudio siguiendo las instrucciones del repositorio de GitHub de NSwagStudio. En la página de la versión NSwag, puede descargar una versión de XCOPY que se puede iniciar sin privilegios de administrador y de instalación.
Inicie NSwagStudio y escriba la URL del archivo
swagger.json
en el cuadro de texto Swagger Specification URL (URL de especificación de Swagger). Por ejemplo,http://localhost:44354/swagger/v1/swagger.json
.Haga clic en el botón Create local Copy (Crear copia local) para generar una representación JSON de la especificación de Swagger.
En el área Salidas, haga clic en la casilla CSharp Client (Cliente de CSharp). En función del proyecto, también puede elegir TypeScript Client (Cliente de TypeScript) o CSharp Web API Controller (Controlador de API web de CSharp). Si selecciona CSharp Web API Controller (Controlador de API web de CSharp), una especificación de servicio volverá a generar el servicio a modo de generación inversa.
Haga clic en Generate Outputs (Generar salidas) para producir una implementación completa del cliente de C# del proyecto TodoApi.NSwag. Para ver el código de cliente generado, haga clic en la pestaña CSharp Client (Cliente de CSharp):
//----------------------
// <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
Sugerencia
El código de cliente de C# se genera en función de las selecciones en la pestaña Settings (Configuración). Modifique esta configuración para realizar tareas como cambiar el nombre del espacio de nombres predeterminado y generar un método sincrónico.
- Copie el código de C# generado en un archivo del proyecto de cliente que usará la API.
- Empiece a consumir la Web API:
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);
Personalización de la documentación de API
Swagger proporciona opciones para documentar el modelo de objetos de cara a facilitar el consumo de Web API.
Información y descripción de la API
En el método Startup.ConfigureServices
, la acción de configuración que se pasa al método AddSwaggerDocument
agrega información, como el autor, la licencia y la descripción:
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"
};
};
});
La interfaz de usuario de Swagger muestra información de la versión:
comentarios XML
Para habilitar los comentarios XML, realice los siguientes pasos:
- Haga clic con el botón derecho en el Explorador de soluciones y seleccione
Edit <project_name>.csproj
. - Agregue manualmente las líneas resaltadas al archivo
.csproj
:
<PropertyGroup>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>
Anotaciones de datos
Dado que NSwag usa Reflection y el tipo de valor devuelto recomendado para acciones de API web es ActionResult<T>, solo puede inferir el tipo de valor devuelto definido por T
. No puede inferir automáticamente ningún otro tipo de valor devuelto.
Considere el ejemplo siguiente:
[HttpPost]
public ActionResult<TodoItem> Create(TodoItem item)
{
_context.TodoItems.Add(item);
_context.SaveChanges();
return CreatedAtRoute("GetTodo", new { id = item.Id }, item);
}
La acción anterior devuelve ActionResult<T>
. Dentro de la acción, se devuelve CreatedAtRoute. Como el controlador tiene el atributo [ApiController]
, también es posible una respuesta BadRequest. Para obtener más información, consulte Respuestas HTTP 400 automáticas. Use las anotaciones de datos para indicar a los clientes qué códigos de estado HTTP se sabe que esta acción devuelve. Marque la acción con los siguientes atributos:
[ProducesResponseType(StatusCodes.Status201Created)] // Created
[ProducesResponseType(StatusCodes.Status400BadRequest)] // BadRequest
En ASP.NET Core 2.2 o versiones posteriores, puede usar las convenciones en lugar de decorar explícitamente acciones individuales con [ProducesResponseType]
. Para más información, consulte Uso de convenciones de API web.
Ahora, el generador de Swagger puede describir con precisión esta acción y los clientes generados sabrán lo que reciben cuando llamen al punto de conexión. Le recomendamos que marque todas las acciones con estos atributos.
Para obtener instrucciones sobre las respuestas HTTP que deben devolver las acciones de la API, consulte RFC 9110: Semántica HTTP (Sección 9.3: Definiciones de métodos).