Ejercicio: Personalización y ampliación de la documentación de OpenAPI con comentarios XML y anotaciones

Completado

En este ejercicio enriquecerá la documentación que ve un desarrollador de su API agregando comentarios y anotaciones al código. En primer lugar, veamos lo que obtenemos de Swagger UI de forma predeterminada.

  1. Para examinar la definición de OpenAPI del punto de conexión de nuestra API en Swagger UI, en su navegador, navegue a http://localhost:5000/swagger. Al seleccionar el método Get, debería ver una salida similar a la siguiente.

    Default Swagger UI for our API.

    Swagger UI nos proporciona información útil sobre la API. Muestra los métodos que puede llamar (en su caso simple, un método denominado PriceFrame). Puede ver que es una operación HTTP Get que adopta dos parámetros necesarios denominados Alto y Ancho. Para ver la llamada de API en acción, puede seleccionar Probarlo, escribir los valores correspondientes al alto y ancho y seleccionar Ejecutar.

    Los usuarios de la API todavía no tienen suficiente información para conocer las limitaciones del método PriceFrame. Vamos a ayudarles incluyendo alguna información más detallada a través de comentarios XML.

Agregar comentarios XML a la API

  1. Vuelva a la instancia de Visual Studio Code que usó en el último ejercicio.

  2. Si la API web sigue ejecutándose en el último ejercicio, presione ctrl+c en Windows o cmd+c en Mac para detenerla.

  3. Para activar la documentación XML en su proyecto, actualice el archivo de proyecto PrintFramerAPI.csproj y agregue la etiqueta GenerateDocumentationFile a la <PropertyGroup> existente y establézcala en true.

    <PropertyGroup>
        <TargetFramework>net7.0</TargetFramework>
        <GenerateDocumentationFile>true</GenerateDocumentationFile>
        <NoWarn>$(NoWarn);1591</NoWarn>
    </PropertyGroup>
    
  4. En Startup.cs, agregue las siguientes instrucciones "using".

    using System.Reflection;
    using System.IO;
    
  5. En Startup.cs, actualice la llamada a AddSwaggerGen() en ConfigureServices para indicar a Swashbuckle que use la documentación XML.

     public void ConfigureServices(IServiceCollection services)
     {
         services.AddControllers();
    
         // Register the Swagger generator, defining 1 or more Swagger documents
         services.AddSwaggerGen(c =>
         {
             c.SwaggerDoc("v1", new OpenApiInfo
             {
                 Version = "v1",
                 Title = "PrintFramer API",
                 Description = "Calculates the cost of a picture frame based on its dimensions.",
                 TermsOfService = new Uri("https://go.microsoft.com/fwlink/?LinkID=206977"),
                 Contact = new OpenApiContact
                 {
                     Name = "Your name",
                     Email = string.Empty,
                     Url = new Uri("https://learn.microsoft.com/training")
                 }
             });
    
             // 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);
         });
     }
    

    En el código anterior, la reflexión determina el nombre del archivo XML para cargar los comentarios XML.

  6. En la carpeta Controladores, abra PriceFrameController.cs. Agregue el siguiente bloque de comentario XML sobre el atributo HttpGet del método GetPrice. Agregar comentarios de barra diagonal triple a una acción mejora Swagger UI, al agregar la descripción al encabezado de sección.

     /// <summary>
     /// Returns the price of a frame based on its dimensions.
     /// </summary>
     /// <param name="Height">The height of the frame.</param>
     /// <param name="Width">The width of the frame.</param>
     /// <returns>The price, in dollars, of the picture frame.</returns>
     /// <remarks> The API returns 'not valid' if the total length of frame material needed (the perimeter of the frame) is less than 20 inches and greater than 1000 inches.</remarks>
     [HttpGet("{Height}/{Width}")]
     public string GetPrice(string Height, string Width)
     {
         string result;
         result = CalculatePrice(Double.Parse(Height), Double.Parse(Width));
         return $"The cost of a {Height}x{Width} frame is ${result}";
     }
    
  7. Para guardar todos los cambios y asegurarse de que se compila localmente, ejecute el siguiente comando en la ventana del terminal de Visual Studio Code.

    dotnet build
    
  8. Para ver los cambios, ejecute la aplicación ASP.NET localmente; para ello, escriba lo siguiente en la ventana del terminal de Visual Studio Code:

    dotnet run
    
  9. Vuelva a ver Swagger UI en http://localhost:5000/swagger y observe la información adicional proporcionada por los comentarios XML a la documentación de OpenAPI.

    Swagger UI with the final documentation from XML comments for our API.

Adición de anotaciones de datos a la API

Use los atributos del espacio de nombres Microsoft.AspNetCore.Mvc para permitir que Swagger mejore la documentación de OpenAPI.

  1. Si la API web sigue ejecutándose en el último ejercicio, presione ctrl+c en Windows o cmd+c en Mac para detenerla.

  2. Para mostrar que la API GetPrice es compatible con una respuesta de tipo de contenido para texto/sin formato, en el controlador de API, PriceFrameController.cs, agregue un atributo [Produces("text/plain")] sobre la definición GetPrice.

    [HttpGet("{Height}/{Width}")]
    [Produces("text/plain")]
    

    La lista desplegable Tipo de contenido de respuesta selecciona este tipo de contenido como el valor predeterminado para las acciones GET del controlador.

Agregar anotaciones de Swashbuckle a la API

Hasta ahora, su API devuelve el código de estado 200 cuando puede calcular el precio de las dimensiones del marco especificado. En la descripción del método GetPrice, observe qué sucede cuando no se puede calcular un precio.

Una forma más sólida de indicar a los desarrolladores los tipos de respuesta y los códigos de error es a través de los siguientes comentarios XML y anotaciones de datos. Las herramientas Swashbuckle y Swagger usan estos valores para generar claramente una descripción OpenAPI de los códigos de respuesta HTTP esperados.

Actualice también el constructor del filtro de verbo HTTP para incluir la propiedad Name e incluya el valor de OpenAPI operationId.

  1. Agregue la siguiente instrucción using al archivo PriceFrameController.cs.

    using Microsoft.AspNetCore.Http;
    
  2. En PriceFrameController.cs, reemplace GetPrice por el código y el comentario siguientes.

    /// <summary>
    /// Returns the price of a frame based on its dimensions.
    /// </summary>
    /// <param name="Height">The height of the frame.</param>
    /// <param name="Width">The width of the frame.</param>
    /// <returns>The price, in dollars, of the picture frame.</returns>
    /// <remarks>
    /// Sample request:
    ///
    ///     Get /api/priceframe/5/10
    ///
    /// </remarks>
    /// <response code="200">Returns the cost of the frame in dollars.</response>
    /// <response code="400">If the amount of frame material needed is less than 20 inches or greater than 1000 inches.</response>
    [HttpGet("{Height}/{Width}", Name=nameof(GetPrice))]
    [Produces("text/plain")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public ActionResult<string> GetPrice(string Height, string Width)
    {
        string result;
        result = CalculatePrice(Double.Parse(Height), Double.Parse(Width));
        if (result == "not valid")
        {
            return BadRequest(result);
        }
        else
        {
            return Ok($"The cost of a {Height}x{Width} frame is ${result}");
        }
    }
    

    Esta actualización de código realiza los cambios siguientes:

    • El método usa los métodos BadRequest() y Ok() para crear un BadRequest (400) y un estado Ok, respectivamente, y especifica el resultado de cadena a la respuesta.
    • Los comentarios XML describen cada código de estado que puede devolver este método.
    • El atributo HttpGet incluye una propiedad Name para emitir el parámetro operationId de OpenAPI.
    • Los atributos ProducesResponseType enumeran las distintas respuestas que puede devolver la acción. Estos atributos se combinan con comentarios XML, como se ha descrito anteriormente, para incluir descripciones representativas con cada respuesta en la instancia de Swagger generada.
  3. Recompile la API web con el siguiente comando:

    dotnet build
    
  4. Ejecute la aplicación ASP.NET con el comando siguiente:

    dotnet run
    
  5. Vuelva a ver Swagger UI en http://localhost:5000/swagger y observe la información adicional que proporcionan estas anotaciones. La siguiente imagen muestra la instancia de Swagger UI final para nuestra API.

    Swagger UI with more documentation from XML comments for our API.

En este ejercicio, ha enriquecido la información que recibe un desarrollador sobre su API, lo que hace que sea más fácil de consumir.