Documentando tu API versionada con Swagger

Jhon Marmolejo - Feb 2 '21 - - Dev Community

En el post anterior vimos lo importante que es versionar nuestra API en .NET Core. En este post veremos como mostrar la documentación de esta API de manera visual usando Swagger.

Documentando tu API sin versionado

Si queremos documentar una API sin versionado debemos seguir los siguientes pasos:

1- Clonar el repositorio con la API versionada de la cual hablamos en el post anterior

git clone https://github.com/jhonmarmolejo/NetCoreApiVersionDemo.git
Enter fullscreen mode Exit fullscreen mode

2- Abrir la solución y añadir los siguientes nugets al proyecto que contiene la API

Install-Package Swashbuckle.AspNetCore.SwaggerGen -Version 5.6.3
Install-Package Swashbuckle.AspNetCore.SwaggerUI -Version 5.6.3
Enter fullscreen mode Exit fullscreen mode

3- Añadimos una nueva clase para extender la configuración de la API con la configuración de Swagger. A esta clase la llamaremos OpenApiConfiguration.cs

using System.IO;
using System.Linq;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;

namespace MyApi.Extensions
{
    internal static class OpenApiConfiguration
    {
        public static IServiceCollection AddCustomOpenApi(this IServiceCollection services)
        {
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API Swagger", Version = "v1" });
                c.IncludeXmlComments(Path.Combine(System.AppContext.BaseDirectory, "MyApi.xml"),true);
                c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
            });

            return services;
        }

        public static void UseCustomSwagger(this IApplicationBuilder app)
        {
            app.UseSwagger();
            app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API Swagger"); });
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Donde en el método AddCustomApi configuramos lo siguiente:

  • El título y la versión de Open Api para la documentación.
c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API Swagger", Version = "v1" });
Enter fullscreen mode Exit fullscreen mode
  • El path que usará Swagger para generar la documentación
c.IncludeXmlComments(Path.Combine(System.AppContext.BaseDirectory, "MyApi.xml"),true);
Enter fullscreen mode Exit fullscreen mode

NOTA: El path que usaremos aqui es del archivo de documentación que genera la API, para esto debemos ir a las propiedades de la API y marcar el check de XML Documentation file

Alt Text

  • Ya que nuestra API de ejemplo es versionada, tenemos que añadir este método para que Swagger resuelva conflictos en el caso de que encuentre endpoints duplicados.
 c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
Enter fullscreen mode Exit fullscreen mode

Y el método UseCustomSwagger nos permite indicar que usaremos la parte visual de Swagger.

4- En Startup.cs, llamamos a services.AddCustomOpenApi(); en el método
ConfigureServices

  public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            services.AddCustomOpenApi();
            ...
            ...
            ...
        }
Enter fullscreen mode Exit fullscreen mode

Y llamamos a app.UseCustomSwagger en el método Configure

 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseCustomSwagger();
            ...
            ...
            ...
        }
Enter fullscreen mode Exit fullscreen mode

5- Ahora sólo queda ejecutar tu API e ir a la url /swagger/index.html

Alt Text

Documentando tu API con versionado

En el caso de que quedaremos documentar nuestra API versionada con Swagger, debemos hacer lo siguiente:

  1. Seguir todos los pasos explicados anteriormente.
  2. Añadir los siguientes filtros

SwaggerRemoveVersionFilter.cs -> quita el parámetro version de la operación

using System.Linq;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace MyApi.Filters
{
    public class SwaggerRemoveVersionFilter : IOperationFilter
    {
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            var versionParameter = operation.Parameters.FirstOrDefault(p => p.Name == "version");

            if (versionParameter != null)
            {
                operation.Parameters.Remove(versionParameter);
            }

        }
    }
}
Enter fullscreen mode Exit fullscreen mode

SwaggerReplaceVersionFilter -> modifica el path que usará Swagger de acuerdo a la versión

using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace MyApi.Filters
{
    public class SwaggerReplaceVersionFilter : IDocumentFilter
    {
        public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
        {
            var paths = swaggerDoc.Paths;
            swaggerDoc.Paths = new OpenApiPaths();

            foreach (var path in paths)
            {
                var key = path.Key.Replace("v{version}", swaggerDoc.Info.Version);
                var value = path.Value;
                swaggerDoc.Paths.Add(key, value);
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

3- En la clase OpenApiConfiguration.cs, modificar el método AddCustomOpenApi para llamar a los nuevos filtros al final.

public static IServiceCollection AddCustomOpenApi(this IServiceCollection services)
        {
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API Swagger v1", Version = "v1" });
                c.SwaggerDoc("v2", new OpenApiInfo { Title = "My API Swagger v2" , Version = "v2" });

                c.IncludeXmlComments(Path.Combine(System.AppContext.BaseDirectory, "MyApi.xml"),true);

                c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
                c.OperationFilter<SwaggerRemoveVersionFilter>();
                c.DocumentFilter<SwaggerReplaceVersionFilter>();
            });

            return services;
        }
Enter fullscreen mode Exit fullscreen mode

4- En la clase Startup.css, modificamos la configuración de OpenApi para usar el versionado por URL, esto lo hacemos para poder lanzar los ejemplos desde la misma interfaz que genera Swagger.

     services.AddApiVersioning(x =>
            {
                x.DefaultApiVersion = new ApiVersion(1, 0);
                x.AssumeDefaultVersionWhenUnspecified = true;
                x.ReportApiVersions = true;
            });
Enter fullscreen mode Exit fullscreen mode

5- Por último vamos a los controllers y añadimos la siguiente cabecera en el inicio de la clase para indicar que usaremos el versionado por url

 [Route("api/v{version:apiVersion}/[controller]")]
 public class DemoController : ControllerBase
 {
    ...
    ...
    ...
 }
Enter fullscreen mode Exit fullscreen mode

6- Ahora sólo queda ejecutar tu API e ir a la url /swagger/index.html donde podemos ver las diferentes versiones de la API

Alt Text

Y podemos lanzar las ejecuciones desde aquí validando que las respuestas son de las versiones que hemos seleccionado

Ejecutando la version 1 de la API

Alt Text

Ejecutando la version 2 de la API

Alt Text

El código de la API versionada con Swagger lo puedes encontrar en la rama feature/ApiWithSwagger en el siguiente repositorio

https://github.com/jhonmarmolejo/NetCoreApiVersionDemo/tree/feature/ApiWithSwagger

Hasta la próxima!!

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player