En esta ocasión les mostrare como integrar documentación en formato swagger a nuestra API de forma automática.
Iniciamos instalando el siguiente paquete Nuget:
Swashbuckle.AspNetCore -Version 5.0.0-rc2
Posteriormente, en el archivo Startup.cs, incluyes el generador de Swagger en el metodo “ConfigureServices”.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
// Register the Swagger generator, defining 1 or more Swagger documents
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v1",
Title = "API Product",
Description = "API Products B2B"
}
);
// 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);
});
}
Y en el método “Configure” habilitas el middleware de Swagger
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
// 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 =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "API Product V1");
});
app.UseHttpsRedirection();
app.UseMvc();
}
Ahora agregaremos cierta configuración al proyecto de tipo API.
Da clic derecho en el proyecto de tipo API y elige la opción “Edit Project File”, posteriormente, agregar las siguientes líneas:
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn>
Quedaría de la siguiente forma:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.3" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0-rc2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ARCA.B2B.Product.Domain\ARCA.B2B.Product.Domain.csproj" />
</ItemGroup>
</Project>
Ahora necesitamos agregar etiquetas de documentación a los controladores y métodos.
En la clase del controlador se agregara el atributo [Produces] para indicar el formato de entrada y salida del API.
[Produces("application/json")]
[Route("api/[controller]")]
[ApiController]
public class ProductController : ControllerBase
En los métodos del controlador se agregaran comentarios en formato de triple diagonal
/// <summary>
/// Get all products, optional filter by segment
/// </summary>
/// <remarks>
/// Sample request:
///
/// GET: api/Product
///
/// </remarks>
/// <param name="Segment">1 - Favoritos, 2 - Destacados</param>
/// <response code="200">Return a list of products</response>
/// <response code="204">Products not found</response>
/// <response code="400">Invalid data</response>
// GET: api/Product
[HttpGet]
[ProducesResponseType(typeof(List<Domain.Entities.Product>), 200)]
public IActionResult Get([FromQuery]Domain.Entities.ProductSegment? Segment)
{
List<Domain.Entities.Product> _products = new List<Domain.Entities.Product>();
if (Segment != null)
_products.Add(new Domain.Entities.Product() { ProductId = "001", ShortDesciption = "Coca Cola 600 ml", Favorite = true });
else
_products.Add(new Domain.Entities.Product() { ProductId = "001", ShortDesciption = "Coca Cola 600 ml" });
return Ok(_products);
}
También se agregara la etiqueta [ProducesResponseType] en los métodos que retornen algún tipo de dato, especificando en tipo de dato a retornar y el código HTTP a responder, tiene que corresponder con alguno de los “Response Code” que se agregaron en los comentarios.
[HttpGet]
[ProducesResponseType(typeof(List<Domain.Entities.Product>), 200)]
public IActionResult Get([FromQuery]Domain.Entities.ProductSegment? Segment)
También es recomendable agregar Data Anotation en las entidades, lo cual hace mas descriptiva la presentación de las entidades en Swagger.
using System.ComponentModel.DataAnnotations;
namespace ARCA.B2B.Product.Domain.Entities
{
public class Favorite
{
[Required]
public int ClientId { get; set; }
[Required]
public string ProductId { get; set; }
}
}
Por ultimo, para consultar la UI de Swagger, partiendo de la siguiente URL del API:
https://localhost:[Port]/api/Product
Se le agrega la siguiente ruta “Swagger/Indez.html” a la URL Root del API
https://localhost:[Port]/Swagger/Index.html
La especificación en formato JSON se consulta igualmente desde el Root agregando “swagger/v1/swagger.json”
https://localhost:[Port]/swagger/v1/swagger.json
Con esto finalizamos, espero les sea de utilidad.