Crea el backend de tus apps con Azure Mobile Apps

Antes de hablar de Mobile Apps tenemos que hablar de Azure App Services.

Azure App Services

Los Azure App Services nos proporcionan todo lo que necesitamos para crear los backends de nuestros clientes web y móviles. Al tratarse de una Plataforma como Servicio, no nos tenemos que preocupar de actualizar el sistema operativo. Además, contamos con seguridad de nivel empresarial, alta disponibilidad, soporte para muchas plataformas y lenguajes de desarrollo, auto-escalado y balanceo de carga, WebJobs para procesamiento en background, fácil despliegue de las aplicaciones incluyendo Despliegue Continuo, así como acceso a datos tanto en el cloud como on-premises.

Podemos elegir entre cuatro tipos de servicios:

image001

Las Web Apps son la evolución de los Azure Websites, y con ellas podemos crear nuestras aplicaciones y servicios web en .NET, Node.js, PHP, Python o Java. Contamos con todas las ventajas que nos proporcionan los App Services, incluyendo el despliegue de nuestro código desde Git, Visual Studio Team Services, CodePlex, GitHub, BitBucket, FTP e incluso DropBox y OneDrive. Podemos utilizar varios slots para esos despliegues. Soportan WebJobs de todo tipo: .cmd, .bat, .exe, .ps1, .sh, .php, .py., .js. Y se integran con Visual Studio. Por no hablar de la posibilidad de utilizar Traffic Manager, de poder hacer backups, de tener conexiones híbridas o redes virtuales para acceder a datos on-premise, de poder tener cache de Redis o utilizar Application Insights.

Las Logic Apps son la evolución de los BizTalk Services, y nos permiten automatizar procesos de negocio de manera muy sencilla, de manera visual y sin utilizar código, y pudiendo utilizar multitud de conectores para integrarnos con nuestras plataformas favoritas de Software como Servicio y aplicaciones empresariales.

Con API Apps podemos crear y consumir APIs fácilmente desde cualquier cliente o desde una Logic App, añadiéndole a nuestras Web Apps metadatos Swagger. Además, nos facilita la autenticación de usuarios, el control de acceso a la API, el poder realizar Single Sign On o lidiar con el versionado de las APIs.

Mobile Apps son la evolución de los Mobile Services, y con ellas podemos crear un backend de manera sencilla para nuestras aplicaciones móviles y webs. Están basadas en Web Apps, lo que les proporciona nuevas capacidades: más tamaños de máquinas virtuales y opciones de instancia, auto-escalado, balanceo de carga, uso de WebJobs, y el resto de ventajas que hemos comentado para las Web Apps.

Entremos más en detalle sobre este último servicio.

Mobile Apps

A día de hoy podemos crear Mobile Apps con Node.js o con .NET. Recientemente hemos anunciado la  disponibilidad general de Mobile Apps y del SDK de servidor para .NET, así como muchas novedades en su actualización de noviembre. El SDK de Node.js todavía está en preview.

Con Mobile Apps podemos crear una API REST que podemos consumir fácilmente con alguno de los SDKs de cliente disponibles para Windows, iOS, Android, HTML5/JavaScript, etc. Esta API y su cliente nos permitirá acceder a diferentes tipos de datos, y podremos sincronizar dichos datos para su acceso offline con poco esfuerzo. Mobile Apps también nos simplifica en gran medida la autenticación de usuarios con Directorio Activo o redes sociales. Y conseguiremos que trabajar con notificaciones Push multi-dispositivo no sea problema alguno.

image003

Veamos un ejemplo de lo que nos supondría hacernos un backend con Mobile Apps y .NET para una pequeña App Universal de Windows 10. La misma complejidad la tendríamos si trabajamos con otras plataformas como iOS o Android.

Ejemplo de Mobile App con .NET

Recientemente participé en el evento benéfico Talks4Kids donde impartí una sesión sobre App Services. Para enseñar la parte de Mobile Apps me creé una pequeña App Universal de Windows 10 que me sirve para crearme la lista de ítems que tengo que meter en mi maleta cuando me voy de viaje.

image005

Para esta app necesitaba un backend que me guardase los ítems y sus grupos en el cloud, para poder acceder a ellos desde cualquiera de mis dispositivos con Windows 10. Para ello me creé una Mobile App con su base de datos SQL Server en el portal de Azure:

image007

Y me descargué del portal el proyecto de Visual Studio de ejemplo para la parte del backend en .NET:

image009

Los datos

A continuación, me creé en el backend un par de clases para los ítems y sus grupos con Entity Framework, que se corresponderán con las tablas que quiero que se creen en la base de datos la primera vez que el cliente de la API quiera crear un objeto del tipo correspondiente. ¡Esa es la magia de Entity Framework Code First!

image011 image013

Y a partir de ellas me creé un par de Table Controllers, uno para cada clase, gracias al scalffolding de Visual Studio.

image015

Estos controladores me proporcionan los métodos necesarios para crear, obtener, modificar y borrar elementos de las tablas de la base de datos. Este es por ejemplo el método generado para obtener un ítem de mi maleta:

image017

Estos métodos son los métodos que expone la API REST a sus clientes. Ahora, gracias a los SDK de cliente que nos proporciona Microsoft, no es necesario que llamemos a la API REST directamente.

En mi app de Windows 10 referencié el paquete NuGet del SDK de cliente:

image018

Y ya pude crear un cliente para mi API:

image020

A ese cliente ya puedo pedirle una tabla con la que trabajar:

image022

Donde T será Item o Group, clases que también he creado en la app cliente. Cualquier operación de inserción, borrado, etc., que haga con esa tabla se convertirá internamente en llamadas a la API REST correspondiente en mi backend y se insertará, borrará, etc., el elemento en la tabla de la base de datos.

Aquí puedes encontrar documentación sobre lo visto hasta ahora: Get Started > Create a Windows app.

Sincronización offline de datos

En el cliente, en lugar de trabajar directamente con una tabla online como la que acabo de mencionar, prefería trabajar con una tabla offline, de manera que las inserciones, borrados, etc., que haga se hagan en local en una base de datos SQLite. Y cuando yo quiera y tenga Internet, que se sincronicen los datos con el servidor.

Para ello tuve que referenciar en el cliente el siguiente paquete NuGet:

image024

Y en lugar de llamar a GetTable hice lo siguiente:

image026

Ahora cualquier operación que haga con la tabla se hará contra una base de datos local de SQLite. Por ejemplo:

image027

Antes de poder utilizar este tipo de tablas tenemos que inicializar la base de datos local:

image029

Este sería el método para sincronizar la base de datos local con la del backend:

image031

Y este el método para limpiar la base de datos local:

image032

También me creé una clase como esta para lidiar con los conflictos de sincronización entre cliente y servidor:

image033

Ahora, ¿qué pasa cuando el usuario accede al backend desde varios clientes, y borra un ítem en uno de ellos? Al borrar el ítem del SQLite y sincronizar, se borrará también del backend. Si luego se conecta desde otro cliente que también tenía dicho ítem en su base de datos local y sincroniza, al no encontrarse el ítem en el backend éste se copia del segundo cliente al servidor. ¡Esto impedirá borrar el ítem del backend! Para solucionar este problema podemos habilitar soft delete en la base de datos del servidor. En el controlador para cuya tabla queramos habilitarlo hacemos lo siguiente:

image035

Ahora los ítems no se borrarán de la tabla de la base de datos del backend. Se marcarán en su lugar como borrados, de manera que todos los clientes que se sincronicen con el backend sepan que tienen que eliminar el ítem de sus respectivos SQLite.

Aquí puedes encontrar más información sobre la sincronización offline: Enable offline sync for your Windows app.

WebJob

Al haber habilitado el soft delete en nuestras tablas de la base de datos del backend, estas tablas no dejarán de crecer, ya que no estamos borrando realmente sus elementos, sólo los marcamos como borrados. Para solucionar esto añadí a mi Mobile App un WebJob que se ejecuta cada cierto tiempo y borra los elementos antiguos. Este es mi método de limpieza:

image037

Y así es llamado cada vez que se ejecute el WebJob:

image039

Aquí tienes más información sobre la creación de WebJobs: Run Background tasks with WebJobs.

Autenticación

Como múltiples usuarios podrían llegar a usar mi app, quería que en el backend se almacenasen los ítems y grupos por usuario, y que cada uno tuviese los suyos propios sin interferir en los de los demás. Además, no quería pedirle al usuario que se crease nuevas credenciales sólo para poder acceder a mi backend, por lo que decidí que utilizase sus credenciales de Twitter para poder utilizar mi app.

Lo primero que tuve que hacer es configurar la autenticación de mi Mobile App en el portal de Azure, y decirle que quería que los usuarios pudiesen usar su cuenta de Twitter para acceder al servicio:

image040Después marqué cada controlador del backend para que requiriese autenticación:

image042

Añadí una propiedad a mis entidades para almacenar en la base de datos a qué usuario corresponde cada elemento:

image044

Y modifiqué los métodos del controlador para guardar en cada elemento el usuario que lo ha creado:

image046

Esto me permite después devolverle a cada usuario sus elementos:

image048

El método para obtener el identificador del usuario sería como el siguiente:

image049

Para pedirle al usuario sus credenciales de Twitter y poder así acceder al backend tan sólo tuve que hacer esto en el cliente:

Si quieres saber más, esta es la documentación que utilicé para crear esta parte del ejemplo:

How to configure your App Service application to use Twitter login Add authentication to your Windows app Expanding App Service Authentication/Authorization Identity / src / Microsoft.AspNet.Identity / PrincipalExtensions.cs

Notificaciones Push

En mi ejemplo también quería enviar una notificación Push a todos los dispositivos donde el usuario estuviese usando el cliente cada vez que insertase, borrase o modificase un elemento en la base de datos, para poder sincronizar automáticamente todos sus clientes con los datos del backend.

Lo primero que tuve que hacer es crear un Azure Notification Hub para la Mobile App en el portal de Azure, y configurarlo para que enviase notificaciones Windows (WNS):

image053

Notification Hub simplifica muchísimo todo el tema de las Notificaciones Push.

Para poder recibir notificaciones Push de mi Mobile App en un cliente Windows tan sólo tenemos que pedirle a Windows un canal y pasárselo al Notification Hub de nuestra Mobile App:

image055

En el backend, para poder enviar notificaciones Push desde los controladores, llamé a un método como el siguiente:

image057

Cuya implementación es esta:

image059

Este método enviará la notificación sólo a los dispositivos de ese usuario concreto, siempre que el usuario se haya autenticado en el cliente antes de registrarse para recibir las notificaciones. Además, entre comentarios puedes ver lo que supondría enviar la notificación Push a otro tipo de dispositivos, como Android.

Si quieres saber más, esta es la documentación que utilicé para crear esta parte del ejemplo:

Add push notifications to your Windows Runtime 8.1 universal app Azure Notification Hubs Send cross-platform notifications to a specific user

 

Espero que te sea de utilidad.

Un saludo,

 

Alejandro Campos Magencio (@alejacma)

Technical Evangelist

PD: Mantente informado de todas las novedades de Microsoft para los desarrolladores españoles a través del Twitter de MSDN, el Facebook de MSDN, el Blog de MSDN y la Newsletter MSDN Flash.