Desarrollar aplicaciones en el cloud mediante desencadenadores y enlaces de funciones

En este capítulo, abordaremos las siguientes recetas:
• Crear una API web back-end mediante desencadenadores de HTTP
• Almacenar datos del empleado mediante enlaces de salida de tablas
de Azure Storage
• Guardar las imágenes de perfil en colas utilizando los enlaces de salida
de cola
• Almacenar la imagen en Azure Blob Storage

Introducción
Cada aplicación de software necesita componentes de back-end que sean responsables de cuidar la lógica empresarial y almacenar los datos en algún tipo
de almacenamiento, como bases de datos y sistemas de archivos. Cada uno de estos componentes de back-end podría desarrollarse utilizando diferentes tecnologías.
La tecnología sin servidor de Azure también nos permite desarrollar estas API de back-end utilizando Azure Functions.
Azure Functions proporciona muchas plantillas listas para usar que resuelven los
problemas más comunes, como la conexión al almacenamiento, la creación de API
web y el recorte de imágenes. En este capítulo, descubriremos cómo usar estas
plantillas integradas. Junto con el aprendizaje de los conceptos relacionados con la
computación sin servidor de Azure, también intentaremos implementar una solución
a un problema de dominio básico de creación de componentes necesarios para que
cualquier organización gestione la información de los empleados internos.
A continuación, vemos un diagrama simple que te ayuda a comprender lo que
lograremos en este capítulo:

Crear una API web back-end mediante desencadenadores de HTTP
Usaremos la arquitectura sin servidor de Azure para crear una API web utilizando
desencadenadores de HTTP. Cualquier aplicación front-end capaz de realizar
llamadas HTTP puede consumir esos desencadenadores de HTTP.
Preparación
Comencemos nuestro viaje para comprender la informática sin servidor de Azure
utilizando Azure Functions mediante la creación de una API web back-end básica
que responde a las solicitudes HTTP:

  • Consulta https://azure.microsoft.com/free/?&wt.mc_id=AID607363_
    SEM_8y6Q27AS para crear una cuenta gratuita de Azure.
  • Visita https://docs.microsoft.com/azure/azure-functions/
    functions-create-function-app-portal para comprender el proceso
    detallado de cómo crear una aplicación de función y https://docs.
    microsoft.com/azure/azure-functions/functions-create-firstazure-
    function crear una función. Al crear una función, también se crea
    una cuenta de almacenamiento para almacenar todos los archivos. Recuerda
    el nombre de la cuenta de almacenamiento, ya que se usará más adelante en
    los otros capítulos.
  • Después de crear la aplicación de función, desplázate por los conceptos
    básicos de desencadenadores y enlaces, que son los conceptos fundamentales
    de cómo funciona Azure Functions. Se recomienda encarecidamente que
    leas el artículo https://docs.microsoft.com/azure/azure-functions/
    functions-triggers-bindings antes de continuar.

«En todo el Post, utilizaremos C# como lenguaje de programación.
La mayoría de las funciones se desarrollan usando el runtime de
Azure Functions V2. Sin embargo, hay algunas recetas que aún no
son compatibles con el runtime V2 que se menciona en la receta
respectiva. Con suerte, para cuando leas este libro, Microsoft
también habrá habilitado esas funciones para el runtime V2.»

Cómo hacerlo…
Sigue estos pasos:

  1. Desplázate a la página de listas Function App haciendo clic en el menú
    Function Apps, que está disponible en el lado izquierdo.
  2. Crea una función nueva haciendo clic en el icono +:
  1. Verás la página Azure Functions para .NET: introducción, donde se te
    pedirá que elijas el tipo de herramientas que te gustaría usar. Puedes
    seleccionar la herramienta en la que estés interesado. En los primeros
    capítulos, usaremos la opción En el portal, donde puedes crear rápidamente
    Azure Functions desde el portal sin herramientas. Más adelante, en los otros
    capítulos, usaremos Visual Studio y Azure Functions Core Tools para crear
    las funciones:
  1. En el paso siguiente, selecciona Más plantillas y haz clic en Finalizar y ver
    plantillas como se muestra en la siguiente captura de pantalla:
  1. En la sección Seleccionar una plantilla a continuación o ir al inicio
    rápido, elige Desencadenador de HTTP para crear una nueva función
    de Desencadenador de HTTP
  1. Proporciona un nombre descriptivo. En este ejemplo, he usado
    RegisterUser como nombre de la función de Azure.
  2. En el menú desplegable Nivel de autorización, selecciona la opción
    Anónimo. Aprenderemos más acerca de todos los niveles de autorización
    en el capítulo 9, Implementar prácticas recomendadas para Azure Functions:
  1. Haz clic en el botón Crear para crear la función de desencadenador de HTTP.
  2. Tan pronto como crees la función, todos los códigos necesarios y los archivos
    de configuración se crearán automáticamente y el archivo run.csx se abrirá
    para que edites el código. Borra el código predeterminado y sustitúyelo por
    el código siguiente. He agregado dos parámetros (firstname y lastname)
    que se mostrarán en la salida cuando se desencadene el desencadenador
    de HTTP:
  1. Guarda los cambios haciendo clic en el botón Guardar que se encuentra justo
    encima del editor de código.
  2. Intentemos probar la función RegisterUser usando la consola de prueba.
    Haz clic en la pestaña Probar para abrir la consola de prueba:
  1. Introduce los valores de firstname y lastname en la sección Cuerpo
    de la solicitud:

Asegúrate de seleccionar POST en el menú desplegable Método HTTP.

  1. Después de revisar los parámetros de entrada, haz clic en el botón Ejecutar
    que se encuentra en la parte inferior de la consola de prueba:
  1. Si la carga de trabajo de la solicitud de entrada se pasa correctamente con
    todos los parámetros necesarios, verás Estado 200 OK y la salida en la
    ventana Salida se mostrará como en la captura de pantalla anterior.

Cómo funciona…
Hemos creado la primera función básica de Azure usando desencadenadores
de HTTP y hemos realizado algunas modificaciones en el código predeterminado.
El código simplemente acepta los parámetros firstname y lastname e imprime
el nombre del usuario final con un mensaje Hola {firstname} {lastname} como
respuesta. También hemos visto cómo probar la función de desencadenador de
HTTP directamente desde el portal de administración de Azure.

En aras de la simplicidad, no he realizado validaciones
del parámetro de entrada. Asegúrate de validar todos los
parámetros de entrada en las aplicaciones que se ejecutan
en tu entorno de producción.

Consulta también
La receta Habilitar autorización para aplicaciones de la función en el capítulo 9,
Implementar prácticas recomendadas para Azure Functions

Almacenar datos del empleado mediante enlaces de salida de tablas de Azure Storage
En la receta anterior, has aprendido a crear un desencadenador de HTTP y a aceptar
los parámetros de entrada. Ahora trabajemos en algo interesante, es decir, donde
se almacenan los datos de entrada en un medio persistente. Azure Functions nos
permite almacenar datos de muchas maneras. Para este ejemplo, almacenaremos
los datos en el almacenamiento de tablas de Azure.

Preparación
En esta receta, descubrirás lo fácil que es integrar un desencadenador de HTTP
y el servicio almacenamiento de tablas de Azure usando enlaces de salida. La
función de desencadenador de HTTP de Azure recibe los datos de varias fuentes y
almacena los datos de perfil de usuario en una tabla de almacenamiento denominada
tblUserProfile. Vamos a seguir los requisitos previos que figuran a continuación:

  • Para esta receta, usaremos el mismo desencadenador de HTTP que creamos
    en nuestra receta anterior.
  • Usaremos Explorador de Azure Storage, que es una herramienta que nos
    ayuda a trabajar con los datos almacenados en la cuenta de Azure Storage.
    La puedes descargar en http://storageexplorer.com/.
  • Puedes obtener más información sobre cómo conectarte a la cuenta de
    almacenamiento usando el Explorador de Azure Storage en https://docs.
    microsoft.com/en-us/azure/vs-azure-tools-storage-manage-withstorage-
    explorer.

Cómo hacerlo…
Sigue estos pasos:

  1. Desplázate a la pestaña Integrar de la función de desencadenador
    de HTTP RegisterUser.
  2. Haz clic en el botón Nueva salida, selecciona Almacenamiento de tablas
    de Azure y, a continuación, haz clic en el botón Seleccionar
  1. Se te pedirá que instales los enlaces y hagas clic en Instalar, lo que llevaría
    unos minutos. Después de instalar los enlaces, selecciona la siguiente
    configuración de los enlaces de salida de almacenamiento de tablas de Azure:
    ° Nombre de parámetro de tabla: es el nombre del parámetro que
    usarás en el método de ejecución de la función de Azure.
    Para este ejemplo, proporciona objUserProfileTable como valor.
    ° Nombre de tabla: se creará una nueva tabla en el almacenamiento
    de tablas de Azure para conservar los datos. Si la tabla aún no existe,
    ¡Azure creará automáticamente una para ti! Para este ejemplo,
    proporciona tblUserProfile como nombre de tabla.
    ° Conexión de la cuenta de almacenamiento: si no ves la cadena
    Conexión de la cuenta de almacenamiento, haz clic en Nuevo
    (como se muestra en la siguiente captura de pantalla) para crear
    una nueva o seleccionar una cuenta de almacenamiento existente.
    ° Los enlaces de salida del almacenamiento de tablas de Azure
    deben ser como se muestran en la siguiente captura de pantalla:
  1. Haz clic en Guardar para guardar los cambios.
  2. Desplázate hasta el editor de código haciendo clic en el nombre de la función
    y pega el código siguiente. El código siguiente acepta la entrada pasada por
    el usuario final y la guarda en el almacenamiento de tablas:
  1. Vamos a ejecutar la función haciendo clic en el botón Ejecutar de la pestaña
    Prueba pasando los parámetros firstname y lastname en el Cuerpo
    de la solicitud:
  1. Si todo ha ido bien, deberías obtener un mensaje Estado 200 OK en el
    cuadro Salida como se muestra en la captura de pantalla anterior. Vamos
    a navegar hasta el explorador de Azure Storage y ver el almacenamiento
    de tablas para comprobar si la tabla denominada tblUserProfile se ha
    creado correctamente:

Cómo funciona…
Azure Functions nos permite integrar fácilmente con otros servicios de Azure
simplemente agregando un enlace de salida al desencadenador. Para este ejemplo,
hemos integrado el desencadenador de HTTP con el enlace de la tabla de Azure
Storage y también hemos configurado la cuenta de Azure Storage al proporcionar
la cadena de conexión de almacenamiento y el nombre de la tabla de Azure Storage
donde nos gustaría crear un registro para cada una de las solicitudes HTTP recibidas
por el desencadenador de HTTP.
También hemos agregado un parámetro adicional para controlar el almacenamiento
de tablas, denominado objUserProfileTable, del tipo CloudTable, al método Run.
Podemos realizar todas las operaciones en el almacenamiento de tablas
de Azure usando objUserProfileTable.

Los parámetros de entrada no se validan en el ejemplo
de código. Sin embargo, en tu entorno de producción, es
importante que los valides antes de almacenarlos en cualquier
tipo de medio persistente.

También hemos creado un objeto UserProfile y lo hemos rellenado con los
valores recibidos en el objeto de solicitud y, a continuación, lo hemos pasado
a una operación de tabla.

Puedes obtener más información acerca del control de operaciones
en el servicio de almacenamiento de tablas de Azure en https://
docs.microsoft.com/en-us/azure/storage/storagedotnet-
how-to-use-tables.

Comprender la conexión de almacenamiento
Al crear una nueva conexión de almacenamiento (consulta el paso 3 de la sección
Cómo hacerlo… de esta receta), se creará una nueva Configuración de la aplicación:

Puedes ir a Configuración de la aplicación haciendo clic en el menú Configuración
de la aplicación disponible en la sección CONFIGURACIÓN GENERAL de la
pestaña Características de la plataforma:

¿Qué es el servicio almacenamiento de tablas de Azure?
El servicio de almacenamiento de tablas de Azure es un medio persistente
de pares de clave-valor NoSQL para almacenar datos semiestructurados.

Podrás obtener más información sobre este tema en https://
azure.microsoft.com/en-in/services/storage/tables/.

Clave de partición y clave de fila
La clave principal de la tabla de almacenamiento de Azure Table tiene dos partes:

  • Clave de partición: los registros del almacenamiento de Azure Table se
    clasifican y organizan en particiones. Cada registro ubicado en una partición
    tendrá la misma clave de partición (p1 en nuestro ejemplo).
  • Clave de fila: se debe asignar un valor único a cada una de las filas.

Y eso no es todo…
Las siguientes son las primeras líneas del código de esta receta:

  • #r «Newtonsoft.json»
  • #r «Microsoft.WindowsAzure.Storage»

Las líneas de código anteriores le indican a la función del runtime que incluya una
referencia de la biblioteca especificada al contexto actual.

Guardar las imágenes de perfil en colas utilizando los enlaces de salida de cola
En la receta anterior, has aprendido a recibir dos parámetros de cadena, firstname
y lastname, en el Cuerpo de la solicitud y a almacenarlos en el almacenamiento de
tablas de Azure. En esta receta, vamos a agregar un parámetro nuevo denominado
ProfilePicUrl para la imagen de perfil del usuario al que se puede acceder
públicamente a través de Internet. En esta receta, descubrirás cómo recibir una
dirección URL de una imagen y guardarla en el contenedor de blobs de una cuenta
de Azure Storage.
Podrías pensar que se podría haber usado el parámetro de entrada ProfilePicUrl
para descargar la imagen de Internet en la receta anterior, Almacenar datos del
empleado mediante enlaces de salida de tablas de Azure Storage. No lo hicimos porque el
tamaño de las imágenes de perfil podría ser enorme con la tecnología moderna y, por
lo tanto, el procesamiento de imágenes sobre la marcha en las solicitudes HTTP podría
dificultar el rendimiento de la aplicación en general. Por esa razón, solo tomaremos la
dirección URL de la imagen del perfil y la almacenaremos en la cola; luego, podremos
procesar la imagen y almacenarla en el blob.

Preparación
Actualizaremos el código de la función RegisterUser que usamos en las recetas
anteriores.

Cómo hacerlo…
Sigue estos pasos:

  1. Desplázate a la pestaña Integrar de la función de desencadenador
    de HTTP RegisterUser.
  2. Haz clic en el botón Nueva salida, selecciona Azure Queue Storage
    y, a continuación, haz clic en el botón Seleccionar.
  3. Proporciona los parámetros siguientes en la configuración de salida
    de Azure Queue Storage:
    ° Nombre del parámetro de mensaje: define el nombre del parámetro
    en objUserProfileQueueItem, que se usará en el método Run
    ° Nombre de cola: define el valor del nombre de cola como
    userprofileimagesqueue
    ° Conexión de cuenta de almacenamiento: asegúrate de seleccionar
    la cuenta de almacenamiento correcta en el campo Conexión de la
    cuenta de almacenamiento
  1. Haz clic en Guardar para crear el nuevo enlace de salida.
  2. Vuelve al editor de código haciendo clic en el nombre de la función
    (RegisterUser en este ejemplo) o el archivo run.csx y realiza los cambios
    marcados en negrita en el código siguiente:

public static async Task Run(
HttpRequest req,
CloudTable objUserProfileTable,
IAsyncCollector objUserProfileQueueItem,
ILogger log)
{
….
string firstname= inputJson.firstname;
string profilePicUrl = inputJson.ProfilePicUrl;
await objUserProfileQueueItem.AddAsync(profilePicUrl);
….
objUserProfileTable.Execute(objTblOperationInsert);
}

  1. En el código anterior, hemos agregado enlaces de salida de cola agregando
    el parámetro IAsyncCollecter al método Ejecutar y simplemente pasando
    el mensaje necesario al método AddAsync, los enlaces de salida se encargarán
    de guardar ProfilePicUrl en la cola. Ahora, haz clic en Guardar para
    guardar los cambios de código en el editor de código del archivo run.csx.
  2. Vamos a probar el código agregando otro parámetro, ProfilePicUrl, al
    Cuerpo de la solicitud y haciendo clic en el botón Ejecutar en la pestaña
    Prueba de la ventana del editor de código de la función de Azure. Es posible
    que la imagen utilizada en el siguiente JSON no exista al leer este libro. Por lo
    tanto, asegúrate de proporcionar una dirección URL válida de la imagen:

{
«firstname»: «Bill»,
«lastname»: «Gates»,
«ProfilePicUrl»:»https://upload.wikimedia.org/wikipedia/
commons/1/19/Bill_Gates_June_2015.jpg»
}

  1. Si todo va bien, verás el mensaje Estado: 200 OK; luego, la dirección URL
    de la imagen que has pasado como un parámetro de entrada en el cuerpo
    de la solicitud se creará como un mensaje de cola en el servicio de cola de
    Azure Storage. Vamos a ir al explorador de Azure Storage y ver la cola
    denominada userprofileimagesqueue, que es el nombre de cola que hemos
    proporcionado en el paso 3. La siguiente es una captura de pantalla del
    mensaje de cola que se creó:

Cómo funciona…
En esta receta, hemos agregado el enlace de salida del mensaje de cola y hemos
hecho los cambios siguientes al código:

  • Hemos agregado un parámetro nuevo denominado out string
    objUserProfileQueueItem, que se usa para enlazar la dirección URL
    de la imagen de perfil como contenido del mensaje de cola
  • Hemos usado el método AddAsync de IAsyncCollector en el método Run,
    que guarda la dirección URL de perfil para la cola como un mensaje de cola.

Almacenar la imagen en Azure Blob Storage
En la receta anterior, almacenamos la dirección URL de la imagen en el mensaje
de cola. Descubramos cómo activar una función de Azure (desencadenador de cola)
cuando se agrega un nuevo elemento de cola al servicio de cola de Azure Storage.
Cada mensaje de la cola es la dirección URL de la imagen de perfil de un usuario,
que Azure Functions procesará y se almacenará como un blob en el servicio Azure
Storage Blob.

Preparación
En la receta anterior, aprendimos a crear enlaces de salida de cola. En esta receta,
tomarás la dirección URL de la cola, crearás una matriz de bytes y luego la escribirás
en un blob.
Esta receta es una continuación de las recetas anteriores. Asegúrate de que las has
implementado.

Cómo hacerlo…
Sigue estos pasos:

  1. Crea una nueva función de Azure seleccionando Desencadenador de Azure
    Queue Storage en las plantillas.
  2. Proporciona los siguientes detalles después de elegir la plantilla:
    ° Asigna un nombre a la función: proporciona un nombre descriptivo,
    como CreateProfilePictures.
    ° Nombre de cola: nombre de la cola userprofileimagesqueue. Esto se supervisará mediante la función de Azure. Nuestra receta anterior creó un nuevo elemento para cada una de las solicitudes válidas que llegan al desencadenador de HTTP (denominado RegisterUser) en la cola userprofileimagesqueue. Para cada nueva entrada de un mensaje de cola a este almacenamiento de cola, el desencadenador CreateProfilePictures se ejecutará automáticamente.
    ° Conexión de cuenta de almacenamiento: conexión de la cuenta de almacenamiento donde se encuentran las colas.
  1. Revisa todos los detalles, haz clic en Crear para crear la nueva función.
  2. Desplázate hasta la pestaña Integrar, haz clic en Nueva salida, selecciona
    Azure Blob Storage y, a continuación, haz clic en el botón Seleccionar.
  3. En la sección Salida de Azure Blob Storage, proporciona lo siguiente:
    ° Nombre del parámetro blob: defínelo en outputBlob
    ° Ruta: defínela en userprofileimagecontainer/{rand-guid}
    ° Conexión de la cuenta de almacenamiento: selecciona la cuenta de
    almacenamiento en la que te gustaría guardar los blobs y haz clic en
    el botón Guardar:
  1. Haz clic en el botón Guardar para guardar todos los cambios.
  2. Sustituye el código predeterminado del archivo run.csx de la función
    CreateProfilePictures por el código siguiente. El siguiente código toma la
    dirección URL de la cola, crea una matriz de bytes y luego la escribe en un blob:

using System;
public static void Run(Stream outputBlob,string
myQueueItem,
TraceWriter log)
{
byte[] imageData = null;
using (var wc = new System.Net.WebClient())
{
imageData = wc.DownloadData(myQueueItem);
}
outputBlob.WriteAsync(imageData,0,imageData.Length);
}

  1. Haz clic en el botón Guardar para guardar los cambios. Asegúrate de que
    no haya errores de compilación en la ventana Registros:
  1. Volvamos a la función RegisterUser y probémosla proporcionando los
    campos firstname, lastname y ProfilePicUrl como lo hicimos en la receta
    Guardar las imágenes de perfil en colas utilizando los enlaces de salida de cola.
  2. Desplázate hasta el explorador de Azure Storage y busca el contenedor
    de blobs userprofileimagecontainer. Encontrarás un blob nuevo:
  1. Puedes ver la imagen en cualquier herramienta (como MS Paint
    o Internet Explorer).

Cómo funciona…
Hemos creado un desencadenador de cola que se ejecuta cuando llega un nuevo
mensaje a la cola. Cuando encuentra un nuevo mensaje de cola, lo lee; como
sabemos, el mensaje es una dirección URL de una imagen de perfil. La función
realiza una solicitud de cliente web, descarga los datos de imagen en forma de matriz
de bytes y luego escribe los datos en el blob, que está configurado como un blob
de salida.

Y eso no es todo…
El parámetro rand-guid generará un GUID nuevo asignado al blob que se crea
cada vez que se activa el desencadenador.

Es obligatorio especificar el nombre del contenedor de blobs en el
parámetro Ruta del enlace de salida de almacenamiento de blobs
mientras se configura la salida de almacenamiento de blobs. Azure
Functions crea uno automáticamente si no existe.
Puedes usar los mensajes de cola solo cuando desees almacenar mensajes
de hasta 64 KB. Si deseas almacenar mensajes de más de 64 KB, debes
usar Azure Service Bus.