Xamarin Forms + Azure Function, desarrollo acelerado y simplificando de aplicaciones Serverless
Tags: webdev, csharp, mobile, dotnet
Published: 2020-03-09 02:48:18

Constantemente en el mundo del desarrollo móvil las apps se conectan a un backend y naturalmente pensamos en una aplicación completa y la infraestructura para ejecutarla, pero que sucede en casos en los que no se necesita de una gran API o Servicio Web, optar por el ciclo natural podría volverse tedioso y trabajoso, para abordar esta problemática Microsoft nos ofrece el servicio en la nube denominado Azure Functions (Serverless). 
Serverless hace referencia a computación sin servidor, un modelo de ejecución en el que el proveedor en la nube en este caso (Azure) es responsable de ejecutar un fragmento de código mediante la asignación dinámica de los recursos. Y cobrando solo por la cantidad de recursos utilizados para ejecutar el código. El código generalmente, se ejecuta dentro de contenedores sin estado que pueden ser activados por una variedad de eventos que incluyen solicitudes HTTP, eventos de base de datos, servicios de colas, alertas de monitoreo, carga de archivos, eventos programados (trabajos cron), etc. El código que se envía al proveedor en la nube para la ejecución es generalmente en forma de una función. Por lo tanto, serverless se denomina “Funciones como servicio” o “FaaS”.

En este Post crearemos una pequeña y sencilla Azure Function desde el portal web de Azure, esta función recibirá algunos parámetros para procesarlos y devolver un resultado esto hará el trabajo de un API, luego crearemos una aplicación móvil multiplataforma con Xamarin Forms para consumirla.

Problema a resolver con este proyecto: **Calcular tu peso ideal**
Para calcular el peso ideal hay que saber manejar el Índice de Masa Corporal (IMC), una medida que nos ayuda a detectar si nos encontramos dentro de los valores saludables o no.
La Organización Mundial de la Salud estima que un peso saludable es el que se sitúa entre valores de 18,5 y 24,9.
Los valores inferiores a 18,5 nos indican un peso demasiado bajo.
Si son iguales o superiores a 25 se consideraría ya sobrepeso. Si supera los 30 se trata de obesidad.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ft1eopeq5fdltg8rwowv.jpg)

El peso ideal se calcula dividiendo el peso en kilogramos por el cuadrado de la altura en metros (kg/m2). Ejemplo: Si una persona pesa 60 kilos y mide 1,50 el resultado final sería 26, 6. Según Aragón, en este ejemplo la persona tendría ligero sobrepeso.
Hay que tener en cuenta que el cálculo del IMC “sólo es válido entre personas de 20 y 65 años y nunca para niños, embarazadas, madres lactantes o personas que realizan mucho deporte o de alta competición”.

> **Definición de tareas Azure Function y Aplicación móvil**
>  Crearemos una aplicación móvil que calculará el peso ideal de una persona, esta recibirá los datos que necesitamos (peso y altura de una persona). Nuestra función de azure hará el procesamiento por medio de una petición HTTP Post, recibirá los datos serializados como un objeto JSON, realizará la operación para obtener el resultado final IMC para finalmente mostrar ese resultado en nuestra aplicación móvil.

## Creando una función de Azure
- En primera instancia necesitas una suscripción de Azure, puedes obtener una aquí https://azure.microsoft.com/es-es/free/

- Después necesitamos crear el recurso, puedes buscarlo en la barra de búsqueda o en la sección de nuevo recurso, selecciona Azure Function.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/zjeoax2zhdkynsaa7z0c.png)


- Necesitamos completar la información obligatoria para crear nuestra Azure Function.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/kjllcb5qjsfpm6bst8xr.png)


![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/33o5h1jv64v9nk1c0hwp.PNG)


- Una vez completados los datos Azure nos mostrará la información con las características de nuestra Azure Function, pulsamos en crear y esperamos a que se cree el recurso, Azure nos notificará cuando todo este listo.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/jcgfnym7sumpb23n0kb1.PNG)


- Una vez creado el recurso necesitamos seguir unos pasos más.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/xe8s488gbhjkij8l2ize.png)


- Debemos elegir un entorno de desarrollo, en este caso seleccionamos en el Portal.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/3ftzxgwnjlikfhrvwie7.PNG)


- Seleccionamos WebHook y API.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/mlkk9mvkqp59jab3h2ud.PNG)


- Al crear una Azure Function esta se crea con código por defecto, eleminaremos ese código y lo sustituiremos por el siguiente y pulsaremos en el botón Guardar y Ejecutar.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/6r2b1n9g6rbpbltqwsdj.PNG)
> **Nota:** Puedes encontrar el código para la función de Azure en el repositorio de github. Link al final de post.

**Tenemos lista nuestra Azure Function!**
- Previo a consumirla desde Xamarin Forms haremos una prueba desde un cliente HTTP en este caso PostMan, necesitamos obtener la url para poder realizar la petición HTTP, da click en la opción *Obtener la dirección URL de la función*.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/exvrwojrt9ittoea3w8f.PNG)

- Ahora vamos a PostMan y utilizamos la Url obtenida en el paso anterior, debemos utilizar el verbo HTTP Post y enviar el objeto JSON en el cuerpo de la petición.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/yyqkaki75a5boo213atx.PNG)

El resultado también es un objeto JSON que contiene una propiedad llamada result, el valor que tiene asignado result es lo que esperamos como respuesta. 

## Creando App Móvil Xamarin Forms
- Para este proyecto utilizaré Visual Studio 2019 Preview, y crearé un proyecto Xamarin Forms 4.3.
- Me apoyaré del patrón de arquitectura de Software MVVM para tratar de desacoplar lo máximo posible la interfaz de usuario de la lógica de la aplicación, buscando factorizar el código de la aplicación en las clases correctas y en establecer la interacción de clases entre sí.

Inicialmente estructuraremos los directorios de la Aplicación de la siguiente manera:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/yjl8fd3yvxardpl9fkm4.PNG)
> **Nota:** la página que se crea por defecto MainPage.xaml fue movida al directorio Views, no olvidar cambiar el namespace en el archivo MainPage.xaml.cs y modificar la referencia en el archivo xaml.

Seguidamente abrimos el administrador de paquetes nugets para la solución y vamos instalar el nuget Newtonsoft.Json en el proyecto NET-Standard.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/75qq3rdy0wgqjzxy2mdw.PNG)

Ahora vamos a crear 3 clases en el directorio Models, las clases modelo se llamaran Response, PesoIdealParam y PesoIdealResult.

Response.cs este modelo hace referencia al resultado que obtenemos al realizar una petición HTTP hacia nuestra Azure Function corriendo en Azure, consta de 4 propiedades: IsSucces toma un valor booleano que depende del éxito o excepción al realizar la petición HTTP, Message almacena el mensaje de respuesta al realizar la petición HTTP, StatusCode como toda petición HTTP retorna un StatusCode este se almacena en esta propiedad y por último DataResult un tipo Object que es capaz de almacenar cualquier tipo de objeto o lista de objetos que pueda retornar la petición HTTP.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/c5avddf8jtkymp8bxj2r.PNG)

PesoIdealParam.cs este modelo lo utilizaremos para enviar los valores recibidos en está app, vamos a serializarlos en formato JSON para luego enviarlos a nuestra Azure Function y se encargue de procesarlos, en este punto tendremos 3 propiedades que necesitaremos enviar: el nombre de la persona, el peso en kilogramos y la altura en metros, las propiedades de clase en C# las manejaremos con mayúsculas aunque en nuestra Azure Function están con minúscula, por eso es necesario utilizar las Anotaciones de Datos [Data Annotations] como decorador de cada propiedad de clase, los Data Annotations poseen el nombre de la propiedad como se gestiona en el backend y el nombre en mayúscula en la propiedad de clase es como gestionamos esa propiedad dentro de la app.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/noquy2rclwig9y2ctrso.PNG)

PesoIdealResult.cs este modelo únicamente posee una propiedad que se encargará de almacenar el resultado recibido del proceso que realiza nuestra Azure Function.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/lf263b1d9jbyaug8jqaq.PNG)

Ahora crearemos una clase llamada AzureFunctionService.cs en el directorio de Services, aquí encapsularemos la lógica para realizar la petición HTTP hacia nuestra Azure Function mediante un método asíncrono de retorna un Task de Response.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/mv3b1w2plr6285fls49o.PNG)
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/n1481kbmcdkku0oj4329.PNG)

El siguiente paso es crear la clase ViewModel llamada MainViewModel.cs en el directorio ViewModels, este archivo encapsula la lógica de la aplicación encargada de utilizar diferentes clases que contienen diferentes responsabilidades.
MainViewModel.cs contiene las propiedades, atributos, validaciones, uso del servicio para utilizar Azure Function dentro de un método que responde al evento de ejecución dentro de un command de Xamarin Forms. 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/gzg9l9ipxakidbcqn2bl.PNG)
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/kjrcb51r2d0dmegukweg.PNG)
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/sy2wenatly1uouk6qap4.PNG)
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/dd5omt6jz6n5lzs58iga.PNG)
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/7v92ggonzqur7k4dqndq.PNG)
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/0n1wuszftc72ay596ec4.PNG)
> MainViewModel.cs hereda de BaseViewModel.cs una clase que contiene una implementación de INotifyPropertyChanged con el evento que notificará los cambios de cada propiedad en la ViewModel.  

En este paso modificaremos la vista MainPage.xaml e inicialmente es necesario agregar la referencia al namespace al que pertenece la clase MainViewModel.cs y seguidamente establecemos el Binding Context para esta página, después creamos los controles necesarios para cada propiedad (Entry, Label, Button, Activity Indicator, etc) y establecemos el Binding correspondiente hacía cada una de las propiedades definidas en la clase ViewModel.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/m79j17eo7yvjr3tqiaef.PNG)
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/0x1qb1g5dgmkhta3bktf.PNG)
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ipeq362fbqv3k4uv54sy.PNG)

Ya tenemos todo el código necesario para ejecutar nuestra app, visualmente se ve de la siguiente manera:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/zk7i7g0l48kjl5i3hgp3.PNG)

Ahora ingresaremos los datos para que nuestra Azure Function pueda procesarlos y devolvernos un resultado, controlando todo desde nuestra app.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/m3oli0ya9no1p1n40atd.PNG)
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/z9zu9we5eym6isd3lzm1.PNG)
> Como podemos observar nuestra aplicación funciona correctamente y podemos verificar los diferentes resultados que podemos obtener con base a la información enviada a nuestra Azure Function.

**Conclusión**
Tradicionalmente, las aplicaciones móviles estaban conectadas a servicios locales. La creación del nivel de servicio requería el conocimiento de la plataforma de servidor y un paradigma de programación. Los desarrolladores trabajaban en configurar los servidores de forma adecuada. A veces se dedicaban días o incluso semanas a la creación de una canalización de implementación confiable y segura, aunque esto se sigue haciendo.
Ahora sabemos que con Azure Functions podemos crear lógica de negocios sin necesidad de convertirnos en expertos en lo relacionado con el servidor, podemos crear un backend en cuestión de minutos y agilizar el desarrollo de nuestras apps móviles.

**Link al Repositorio en GitHub**
https://github.com/EbarriosCode/Xamarin-Azure-Functions

**Referencias**
https://docs.microsoft.com/en-us/azure/azure-functions/
https://docs.microsoft.com/en-us/xamarin/xamarin-forms/data-cloud/azure-services/azure-functions?tabs=windows
https://cuidateplus.marca.com/alimentacion/diccionario/indice-masa-corporal-imc.html
https://www.efesalud.com/aprende-calcular-peso-saludable/