Creación de API sin servidor en Visual Studio usando Azure Functions y la integración de API Management

Las API de REST a menudo se describen con una definición de OpenAPI (anteriormente conocida como el archivo Swagger). Este archivo contiene información acerca de operaciones en una API y sobre cómo se deben estructurar los datos de la solicitud y la respuesta para dicha API.

En este tutorial, aprenderá a:

  • Creación del proyecto de código en Visual Studio
  • Instalación de la extensión OpenAPI
  • Adición de un punto de conexión de desencadenador HTTP, que incluye definiciones de OpenAPI
  • probar localmente API de función mediante la funcionalidad integrada de OpenAPI;
  • Publicar proyecto en una aplicación de funciones en Azure
  • Habilitar la integración con API Management
  • descargar el archivo de definición de OpenAPI.

La función sin servidor que cree proporciona una API con la que puede determinar si resulta rentable una reparación de emergencia en una turbina eólica. Dado que crea tanto la aplicación de funciones como la instancia de API Management en un nivel de consumo, el costo para completar este tutorial es mínimo.

Requisitos previos

Creación del proyecto de código

La plantilla del proyecto de Azure Functions de Visual Studio crea un proyecto que puede publicar en una aplicación de función en Azure. También creará una función desencadenada por HTTP a partir de una plantilla que admita la generación de archivos de definición de OpenAPI (anteriormente archivo Swagger).

  1. En el menú de Visual Studio, seleccione Archivo>Nuevo>Proyecto.

  2. En Crear un proyecto, escriba functions en el cuadro de búsqueda, elija la plantilla Azure Functions y seleccione Siguiente.

  3. En Configurar el nuevo proyecto, rellene el campo Nombre del proyecto (por ejemplo, TurbineRepair) y seleccione Crear.

  4. Para la configuración Crear una nueva aplicación de Azure Functions, seleccione una de estas opciones para Trabajo de Functions, donde la opción que elija depende del modelo de proceso elegido:

    .NET 8.0 Aislado (compatibilidad a largo plazo): las funciones de C# se ejecutan en el modelo de trabajo aislado, que se recomienda. Para obtener más información, consulte la guía del modelo de trabajo aislado.

  5. Para el resto de las opciones, use los valores de la tabla siguiente:

    Configuración valor Descripción
    Plantilla de función Vacía Esto crea un proyecto sin un desencadenador, lo que proporciona más control sobre el nombre de la función desencadenada por HTTP al agregarlo más adelante.
    Usar Azurita para la cuenta de almacenamiento de runtime (AzureWebJobsStorage) Selected Puede usar el emulador para el desarrollo local de funciones de desencadenador HTTP. Dado que una aplicación de funciones de Azure necesita una cuenta de almacenamiento, se asigna o se crea una cuando publica su proyecto en Azure.
    Nivel de autorización Función Cuando se ejecutan en Azure, los clientes deben proporcionar una clave al acceder al punto de conexión. Para obtener más información, consulte Nivel de autorización.
  6. Seleccione Crear para crear el proyecto de función.

A continuación, actualice el proyecto mediante la instalación de la extensión OpenAPI para Azure Functions, lo que permite la detectabilidad de los puntos de conexión de API en la aplicación.

Instalación de la extensión OpenAPI

Para instalar la extensión OpenAPI:

  1. En el menú Herramientas, seleccione Administrador de paquetes NuGet>Consola del Administrador de paquetes.

  2. En la consola, ejecute el siguiente comando Install-Package para instalar la extensión OpenAPI:

    NuGet\Install-Package Microsoft.Azure.Functions.Worker.Extensions.OpenApi -Version 1.5.1
    

    Es posible que tenga que actualizar la versión específica, en función de la versión de .NET.

Ahora, puede agregar la función de punto de conexión HTTP.

Adición de una función de punto de conexión HTTP

En una biblioteca de clases de C#, los enlaces usados por la función se definen aplicando atributos en el código. Para crear una función con un desencadenador HTTP:

  1. En el Explorador de soluciones, haga clic con el botón derecho en el nodo del proyecto y seleccione Agregar>Nueva función de Azure Functions.

  2. Escriba Turbine.cs para la clase y, a continuación, seleccione Agregar.

  3. Elija la plantilla Desencadenador Http, establezca Nivel de autorización en Función y, a continuación, seleccione Agregar. Se agrega un archivo de código Turbine.cs al proyecto que define un nuevo punto de conexión de función con un desencadenador HTTP.

Ahora puede reemplazar el código de plantilla del desencadenador HTTP por código que implementa el punto de conexión de la función Turbine, junto con los atributos que usan OpenAPI para definir el punto de conexión.

Actualización del código de la función

La función usa un desencadenador HTTP que toma dos parámetros:

Nombre de parámetro Descripción
hours Tiempo estimado para reparar una turbina, redondeado a la hora completa más cercana.
capacidad La capacidad de la turbina, en kilovatios.

A continuación, la función calcula el coste de la reparación y los ingresos que podría generar la turbina en un período de 24 horas. Los parámetros se proporcionan en la cadena de consulta o en la carga de una solicitud POST.

En el archivo de proyecto Turbine.cs, reemplace el contenido de la clase generada a partir de la plantilla de desencadenador HTTP por el código siguiente, que depende del modelo de proceso:

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json;
using System.Net;

namespace TurbineRepair
{
    public class Turbine
    {
        const double revenuePerkW = 0.12;
        const double technicianCost = 250;
        const double turbineCost = 100;

        private readonly ILogger<Turbine> _logger;

        public Turbine(ILogger<Turbine> logger)
        {
            _logger = logger;
        }

        [Function("TurbineRepair")]
        [OpenApiOperation(operationId: "Run")]
        [OpenApiSecurity("function_key", SecuritySchemeType.ApiKey, Name = "code", In = OpenApiSecurityLocationType.Query)]
        [OpenApiRequestBody("application/json", typeof(RequestBodyModel),
            Description = "JSON request body containing { hours, capacity}")]
        [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(string),
            Description = "The OK response message containing a JSON result.")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            // Get request body data.
            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic? data = JsonConvert.DeserializeObject(requestBody);
            int? capacity = data?.capacity;
            int? hours = data?.hours;

            // Return bad request if capacity or hours are not passed in
            if (capacity == null || hours == null)
            {
                return new BadRequestObjectResult("Please pass capacity and hours in the request body");
            }
            // Formulas to calculate revenue and cost
            double? revenueOpportunity = capacity * revenuePerkW * 24;
            double? costToFix = hours * technicianCost + turbineCost;
            string repairTurbine;

            if (revenueOpportunity > costToFix)
            {
                repairTurbine = "Yes";
            }
            else
            {
                repairTurbine = "No";
            };

            return new OkObjectResult(new
            {
                message = repairTurbine,
                revenueOpportunity = "$" + revenueOpportunity,
                costToFix = "$" + costToFix
            });
        }
        public class RequestBodyModel
        {
            public int Hours { get; set; }
            public int Capacity { get; set; }
        }
    }
}

Este código de función devuelve un mensaje de Yes o No para indicar si una reparación de emergencia es rentable. También devuelve la oportunidad de ingresos que representa la turbina y el costo de repararla.

Ejecución y comprobación locales de la API

Al ejecutar la función, los puntos de conexión de OpenAPI hacen que resulte fácil probar la función localmente usando una página generada. No es necesario proporcionar claves de acceso de función cuando se ejecuta localmente.

  1. Presione F5 para iniciar el proyecto. Cuando el entorno de ejecución de Functions se inicia localmente, se muestra un conjunto de puntos de conexión de OpenAPI y Swagger en la salida, junto con el punto de conexión de la función.

  2. En el explorador, abra el punto de conexión RenderSwaggerUI, que debe tener un aspecto parecido a http://localhost:7071/api/swagger/ui. Se representa una página en función de las definiciones de OpenAPI.

  3. Seleccione POST>Pruébelo, especifique valores para hours y capacity, ya sea como parámetros de consulta o en el cuerpo de la solicitud JSON, y seleccione Ejecutar.

    IU de Swagger UI para probar la API TurbineRepair

  4. Si especifica valores enteros, como 6 para hours y 2500 para capacity, obtendrá una respuesta JSON similar al siguiente ejemplo:

    Datos JSON de respuesta de la función TurbineRepair

Ahora ya existe una función que determina la rentabilidad de las reparaciones de emergencia. A continuación, publique el proyecto y las definiciones de API en Azure.

Publicar el proyecto en Azure

Para poder publicar el proyecto, debe tener una aplicación de funciones en la suscripción de Azure. La publicación de Visual Studio crea una aplicación de funciones la primera vez que publica su proyecto. También puede crear una instancia de API Management que se integra con su aplicación de funciones para exponer la API TurbineRepair.

  1. En el Explorador de soluciones, haga clic con el botón derecho en el proyecto y seleccione Publicar, en Destino, seleccione Azure y, a continuación, seleccione Siguiente.

  2. En Destino específico, elija Aplicación de funciones de Azure (Windows) , para crear una aplicación de funciones que se ejecute en Windows, y seleccione Siguiente.

  3. En Instancia de la función, seleccione + Crear una nueva función de Azure… .

    Creación de una nueva instancia de aplicación de funciones

  4. Crear una nueva instancia con los valores especificados en la tabla siguiente:

    Configuración valor Descripción
    Nombre Nombre único globalmente Nombre que identifica de forma única la nueva aplicación de función. Acepte este nombre o escriba uno nuevo. Los caracteres válidos son a-z, 0-9 y -.
    Suscripción Su suscripción La suscripción de Azure que se va a usar. Acepte esta suscripción o seleccione una nueva en la lista desplegable.
    Grupo de recursos Nombre del grupo de recursos Nombre del grupo de recursos en el que se va a crear la aplicación de función. Seleccione un grupo de recursos existente en la lista desplegable o elija la opción Nuevo para crear un nuevo grupo de recursos.
    Tipo de plan Consumo Cuando publique el proyecto en una aplicación de funciones que se ejecute en un plan Consumo, solo pagará por las ejecuciones de la aplicación. Otros planes de hospedaje suponen costos más elevados.
    Ubicación Ubicación del servicio Elija una ubicación en una región próxima a usted o a otros servicios a los que las funciones accedan.
    Azure Storage Cuenta de almacenamiento de uso general El entorno de ejecución de Functions necesita una cuenta de Azure Storage. Seleccione Nueva para configurar una cuenta de almacenamiento de uso general. También puede elegir una cuenta existente que cumpla los requisitos de la cuenta de almacenamiento.

    Creación de una aplicación de funciones con Storage

  5. Seleccione Crear para crear una aplicación de funciones y sus recursos relacionados en Azure. El estado de la creación del recurso se muestra en la parte inferior izquierda de la ventana.

  6. En Instancia de Functions, asegúrese de que la opción Ejecutar desde archivo de paquete esté activada. La aplicación de funciones se implementa con la implementación de un archivo zip y con el modo de ejecución desde el paquete habilitado. Este es el método de implementación recomendado para su proyecto de Functions, ya que proporciona un mejor rendimiento.

  7. Seleccione Siguiente y, en la página API Management, elija también + Crear una API de API Management.

  8. Para crear una API en API Management, use los valores de la siguiente tabla:

    Configuración valor Descripción
    Nombre de la API TurbineRepair Nombre de la API.
    Nombre de la suscripción Su suscripción La suscripción de Azure que se va a usar. Acepte esta suscripción o seleccione una nueva en la lista desplegable.
    Grupos de recursos Nombre del grupo de recursos En la lista desplegable, seleccione el mismo grupo de recursos que la aplicación de funciones.
    Servicio API Management Nueva instancia Seleccione Nuevo para crear una nueva instancia de API Management en la misma ubicación en el nivel sin servidor. Seleccione Aceptar para crear la instancia.

    Creación de una instancia de API Management con una API

  9. Seleccione Crear para crear la instancia de API Management con la API TurbineRepair a partir de la integración de funciones.

  10. Seleccione Finalizar y, una vez completado el proceso de creación del perfil de publicación, seleccione Cerrar.

  11. Compruebe que la página Publicar ahora indica Listo para publicar y, a continuación, seleccione Publicar para implementar el paquete que contiene los archivos del proyecto en la nueva aplicación de funciones de Azure.

    Una vez finalizada la implementación, en la pestaña Publicar aparecerá la dirección URL raíz de la aplicación de funciones de Azure.

Obtención de la clave de acceso de función

  1. En la pestaña Publicar, seleccione los puntos suspensivos ( ) junto a Hospedaje y seleccione Abrir en Azure Portal. La aplicación de funciones que ha creado se abrirá en Azure Portal en su navegador predeterminado.

  2. En Funciones en la página Información general, seleccione >Turbine y, a continuación, seleccione Claves de función.

    Obtención de una clave de acceso para la función TurbineRepair

  3. En Teclas de función, seleccione el icono copiar en el Portapapeles junto a la clave predeterminada. Ahora puede establecer esta clave que copió en API Management para que pueda acceder al punto de conexión de la función.

Configuración de API Management

  1. En la página de la aplicación de funciones, expanda API y seleccione API Management.

  2. Si la aplicación de funciones aún no está conectada a la nueva instancia de API Management, selecciónela en API Management, seleccione API>Documento de OpenAPI en Azure Functions, asegúrese de que las funciones de importación estén activadas y seleccione Vincular API. Asegúrese de que solo TurbineRepair esté seleccionado para importar y, a continuación, Seleccione.

  3. Seleccione Ir a API Management en la parte superior de la página y, en la instancia de API Management, expanda API.

  4. En API>Todas las API, seleccione Documento OpenAPI en Azure Functions>Ejecución POSTy, a continuación, en Procesamiento de entrada seleccione Agregar directiva>Establecer parámetros de consulta.

  5. En Procesamiento de entrada, en Establecer parámetros de consulta, escriba code en Nombre, seleccione + Valor, pegue la clave de función que se copió y seleccione Guardar. API Management incluye la clave de función cuando pasa llamadas al punto de conexión de la función.

    Proporcionar credenciales de función a la regla de procesamiento de entrada de la API

Ahora que la clave de función está establecida, puede llamar al punto de conexión de API turbine para comprobar que funciona cuando se hospeda en Azure.

Comprobación de la API en Azure

  1. En la API, seleccione la pestaña Prueba y Ejecución POST. A continuación, especifique el siguiente código en Cuerpo de la solicitud>Sin formato y seleccione Enviar:

    {
        "hours": "6",
        "capacity": "2500"
    }
    

    Página de prueba de OpenAPI en la API de API Management

    Como antes, también puede proporcionar los mismos valores que los parámetros de consulta.

  2. Seleccione Enviar y, a continuación, consulte la respuesta HTTP para comprobar que la API devuelve los mismos resultados.

Descarga de la definición de OpenAPI

Si la API funciona según lo previsto, puede descargar la definición de OpenAPI para las nuevas API hospedadas desde API Management.

    1. En API, seleccione Documento OpenAPI en Azure Functions, seleccione los tres puntos suspensivos () y seleccione Exportar.

    Descarga de la definición de OpenAPI

  1. Elija el medio de exportación de API, incluidos los archivos OpenAPI en varios formatos. También puede exportar API de Azure API Management a Power Platform.

Limpieza de recursos

En los pasos anteriores, creó recursos de Azure en un grupo de recursos. Si no cree que vaya a necesitar estos recursos en el futuro, puede eliminarlos mediante la eliminación del grupo de recursos.

En el menú de Azure Portal o la página Inicio, seleccione Grupos de recursos. A continuación, en la página Grupos de recursos, seleccione el grupo que ha creado.

En la página myResourceGroup, asegúrese de que los recursos enumerados sean los que desea eliminar.

Seleccione Eliminar grupo de recursos, escriba el nombre de su grupo en el cuadro de texto para confirmar la acción y, a continuación, seleccione Eliminar.

Pasos siguientes

Ha usado Visual Studio 2022 para crear una función que se autodocumenta debido a la extensión OpenAPI y está integrada con API Management. Ahora puede refinar la definición de API Management en el portal. También puede obtener más información acerca de API Management.