Los servicios que ofrece Azure Serverless da la opción a los desarrolladores de implementar soluciones de una forma ágil, rápida, eficaz y auto escalables.
Esto permite a los desarrolladores centrarse en lo importante, en las aplicaciones en sí, y dejar un poco de lado las tareas de organizar, administrar y escalar las infraestructuras. Para ello, Azure ofrece una serie de herramientas que ayudan a agilizar este proceso fácilmente.
En el proceso normal de diseño de una aplicación, hasta hoy, se tenia que dedicar un tiempo al análisis, diseño y estimación de la infraestructura donde queríamos alojar dicha aplicación. Con Azure ServerLess podemos evitar todo esto, centrándonos directamente en el código y ahorrando tiempo.
Azure ofrece un listado de servicios totalmente administrados que contemplan bases de datos, inteligencia, análisis, monitoreo, calculo, etc. para facilitar el desarrollo de aplicaciones en un abanico amplio de escenarios.
En este post nos vamos a centrar en dos servicios para el desarrollo de aplicaciones sin servidor como son Azure Functions y Azure LogicApps.
- Azure Logic Apps ofrece flujos de trabajo serverless en cloud. Logic Apps cuenta con infinidad de conectores a distintos servicios como SalesForce, SAP, SQL, etc. Un ejemplo de uso de LogicApps puede ser la necesidad de trazar los cambios que se producen en una tabla SQL. Será el ejemplo práctico que veremos a continuación.
- Azure Functions nos ofrece Functions-as-a-service. Nos permite ejecutar Código mediante peticiones en distintos lenguajes (c#, javascript, Python, etc.). Una función puede ser desencadenada mediante una llamada HTTP o por un evento de una cola o un blob de una cuenta de almacenamiento y se puede desarrollar y probar de manera local. Una vez desplegada podemos saber que se escalara para cumplir con la demanda que tenga.
Comenzando con el caso práctico vamos a montar un flujo de trabajo en Logic Apps que este escuchando cambios en una tabla SQL, para procesar los nuevos registros, hacer una llamada HTTP a una Azure Function que trabajará con esos datos y emitirá un mensaje a una cola en una cuenta de almacenamiento, para así informar a un sistema externo de los cambios producidos en la tabla SQL.
Para empezar, vamos a crear la Azure Logic App y la Azure Function desde el portal de Azure.
Una vez creados los servicios, procedemos a implementar el flujo de Logic App y el código de la Azure Function, para ello damos por hecho que tenemos una base de datos creada, con una tabla con cualquier estructura, en nuestro caso, vamos a tener una tabla con modelos y precios de coche. También se da por hecho que vamos a tener una cuenta de almacenamiento creada y una cola a la que poder emitir los mensajes desde la Azure Function.
Para la Azure Function tenemos el siguiente código:
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Azure.WebJobs; using Microsoft.Azure.WebJobs.Extensions.Http; using Microsoft.Extensions.Logging; using Microsoft.WindowsAzure.Storage; using Microsoft.WindowsAzure.Storage.Queue; using Newtonsoft.Json; using System; using System.IO; using System.Threading.Tasks; using Microsoft.Extensions.Configuration; namespace BraventServerLessAzf1 { public static class Function1 { [FunctionName("Function1")] public static async Task Run( [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req, ILogger log, ExecutionContext context) { log.LogInformation("C# HTTP trigger function processed a request."); var config = new ConfigurationBuilder() .SetBasePath(context.FunctionAppDirectory) .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true) .AddEnvironmentVariables() .Build(); string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); Marca data = JsonConvert.DeserializeObject(requestBody); string message = $"Nuevo modelo dado de alta el {data.fecha}: {data.marca} {data.modelo} con un precio de {data.precio} euros"; //Get queue configuration CloudStorageAccount storageAccount = CloudStorageAccount.Parse(config.GetConnectionString("ConnectionStringSTA")); CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient(); CloudQueue queue = queueClient.GetQueueReference("marcas"); //Send message to queue CloudQueueMessage queueMessage = new CloudQueueMessage(message); await queue.AddMessageAsync(queueMessage); // Create the queue if it doesn't already exist await queue.CreateIfNotExistsAsync(); return data != null ? (ActionResult)new OkObjectResult(message) : new BadRequestObjectResult("Please pass a name on the query string or in the request body"); } } public class Marca { public int id { get; set; } public string marca { get; set; } public string modelo { get; set; } public int precio { get; set; } public DateTime fecha { get; set; } } }
Publicamos la Azure Function desde visual studio y daremos de alta la cadena de conexión de la cuenta de almacenamiento en los connection strings del site.
Ahora implementamos el flujo de la Logic App:
- Añadimos una actividad de SQL para que se lance cuando hay un nuevo registro en la tabla de marcas de coches
A continuación, enlazamos una actividad para llamar a la Azure Function anterior con los parámetros del registro nuevo de base de datos.
De esta forma, al añadir un nuevo registro a la base de datos, se lanzará un flujo de la Logic App, que llamar a la AZF y esta a su vez, enviará el mensaje a la cola.
Como podemos ver, tras añadir un registro a la tabla de marcas en SQL, se desencadena una ejecución de la LogicApp, la llamada a la AZF y el posterior envío a la cola de la cuenta de almacenamiento.
En posteriores posts, veremos cómo securizar las llamadas entre Azure Functions y Logic Apps, además de otro tipo de actividades dentro del flujo de las Logic Apps.
Escrito por: Pedro Sánchez, technology team leader en Bravent.