Blog de Amazon Web Services (AWS)
Mobile Backend as a Service Patrón de Arquitectura
Introducción
Mobile Backend as a Service o simplemente MBaaS, es un modelo de arquitectura donde recursos de backend que soportan aplicaciones móviles son aprovisionados y operados como servicio administrado. En este modelo, todo el detalle interno de mantener alta disponibilidad de los servicios, escalar la capacidad de acuerdo con la demanda y adaptarse respondiendo a fallas de componentes de infraestructura, son realizados de forma transparente por AWS. Al liberar el equipo técnico de todo el trabajo de mantener una infraestructura de operaciones, las empresas pueden dedicar más tiempo y esfuerzo en los aspectos que más diferencian su aplicación de las otras existentes, como por ejemplo, creación de nuevas funcionalidades, interfaces y detalles en la usabilidad. Además de esto, el modelo permite una fácil reutilización de componentes de backend porque ellos generalmente cuentan con APIs para una fácil integración con otros módulos de la misma aplicación (ejemplo: interface web) o hasta aplicaciones distintas que necesitan del mismo servicio.
Este artículo está estructurado de la siguiente forma: inicialmente describiremos los servicios de AWS que pueden ser utilizados para soportar una arquitectura MBaaS; en seguida detallaremos cómo estos servicios pueden ser integrados de forma que podamos montar un patrón de arquitectura que soporta aplicaciones semejantes; para facilitar la lectura de esta estructura, junto con el arquitecto de AWS Fabio Silva, montamos un ejemplo de aplicación y destacamos algunos segmentos de código para demostrar detalles de la implementación de la solución y por último, revisaremos los principales conceptos, puntos de atención de la solución y listaremos algunos productos más que pueden ser usados para complementar la arquitectura presentada aquí.
Se asume que los lectores conocen y tienen experiencia con desarrollo para dispositivos móviles. El artículo no abordará informaciones sobre tecnologías y estructuras de arquitectura de aplicación (client side). A pesar que tenemos algunos ejemplos de código para la plataforma Android, el foco es estudiar lo que ocurre del lado del backend de estas aplicaciones.
Componentes
Dentro de la cama de soluciones actualmente ofrecidas por AWS, destacamos los siguientes servicios que utilizamos para estructurar los componentes de backend de la arquitectura propuesta. Aquí haremos una descripción de cada uno de estos servicios con breves indicaciones del papel que ellos juegan dentro del modelo MBaaS.
AWS SDK: desarrollo de la aplicación
AWS cuenta con diferentes SDKs para facilitar el desarrollo de aplicaciones que integran o hacen uso de los servicios de AWS. Actualmente AWS cuenta con SDKs para desarrollo en Java, .Net, Node.js, PHP, Python, Ruby, Go y JavaScript en el browser. También están disponibles SDKs para plataformas móviles como FireOS, Android, iOS y Unity.
Amazon S3: hosting de sitios estáticos
Amazon Simple Storage Service (S3) es un servicio de almacenamiento de objetos vía web donde el usuario es cobrado solamente por la utilización de recursos – volumen de datos almacenados, peticiones y transfer out -. El servicio fue diseñado para tener alta durabilidad, disponibilidad y escalar su capacidad de acuerdo con la demanda de recursos. S3 puede ser configurado para funcionar como web server para sitios estáticos y las llamadas al backend de las páginas de estos sitios, pueden ser realizadas vía peticiones GET/POST o hasta haciendo uso del SDK JavaScript para acceder directamente los resultados de AWS.
CloudFront: aumento de desempeño para entrega de contenido web
Amazon CloudFront puede ayudar a aumentar el desempeño de sus aplicaciones web y disminuir significativamente la latencia de entrega del contenido a sus clientes. El servicio hace uso de una red global de puntos de presencia que almacenan en caché, copias de los archivos con más peticiones o próximos a sus visualizadores. Al igual que otros servicios de AWS, CloudFront es una oferta de auto servicio, cobrada por el uso, sin exigencia de compromisos a largo plazo o tazas mínimas.
Amazon DynamoDB: base de dados no relacional
Es un servicio de base de datos no relacional (NoSQL). De una forma similar a los otros servicios administrados presentados aquí, todo el trabajo para garantizar la alta disponibilidad del servicio, durabilidad de los datos y estructurar sus componentes internos para atender el desempeño especificado en las tablas del banco, son realizados por la solución de forma transparente.
Amazon Cognito: autenticación, autorización y sincronización de datos
Amazon Cognito es un servicio que permite guardar fácilmente datos móviles de usuarios tales como preferencias de aplicaciones o estados de juegos en AWS. Todo esto sin necesidad de desarrollar ningún código de backend o de administrar una infraestructura. Los datos pueden ser guardados localmente en los dispositivos de los usuarios, permitiendo que la aplicación funcione incluso cuando el dispositivo esté temporalmente sin acceso a internet. Otra funcionalidad bastante útil de este producto es la integración con proveedores de login públicos como Facebook, Twitter, entre otros. El siguiente post de blog describe en detalle el proceso de autenticación y autorización de Amazon Cognito: https://bit.ly/1ZjAFyP
AWS Lambda: ejecutar código basado en eventos
Servicio de computación que permite ejecutar programas en respuesta a un evento que puede ser un upload de un archivo a Amazon S3, una escritura de una nueva información en DynamoDB, una llamada directa vía el SDK de AWS, o incluso como resultado de un evento agendado de ejecución recurrente. Para cada evento, AWS Lambda reserva los recursos de computación necesarios y ejecuta su programa. Con esta solución es posible implementar rutinas de backend sin la necesidad de tener que mantener una infraestructura compleja (con alta disponibilidad) para tal fin.
Amazon API Gateway: punto de entrada para el backend
Amazon API Gateway es un servicio totalmente administrado que permite que los desarrolladores creen, publiquen, operen, monitoreen y protejan APIs en cualquier escala. El servicio procesa todas las tareas relacionadas a acceso y procesamiento de hasta centenares de miles de llamadas simultaneas de APIs, incluyendo también la administración de tráfico, autorización, control de acceso, monitoreo y administración de versiones de las APIs.
Amazon CloudSearch: indexación y búsqueda
Motor administrado de búsqueda administrado que requiere mínimo mantenimiento. Con este servicio es posible implementar de forma simple, una solución de búsqueda para su aplicación. Las características de escalabilidad de Amazon CloudSearch son múltiples (ejemplo: podemos aumentar la capacidad de procesamiento y memoria de los nodos del clúster o simplemente adicionar más nodos a la estructura) y, nuevamente no hay necesidad de preocuparse con detalles de operación de infraestructura donde el servicio opera.
Amazon SNS: notificaciones vía push
Amazon Simple Notification Service (SNS) es un servicio administrado que permite fácil implementación de un sistema de notificación para su aplicación. Integrado con las principales soluciones de notificaciones existente: envío de notificaciones push para Apple iOS, Android y otros dispositivos móviles, como también para destinos como filas de Amazon SQS, funciones AWS Lambda, direcciones de email, SMS (por el momento solamente en EEUU) y endpoints HTTP.
Amazon Mobile Analytics: monitoreo de uso de la aplicación
El servicio de Amazon Mobile Analytics permite que los administradores de una aplicación móvil, monitoreen múltiples métricas de uso de su aplicación. Algunas de las métricas más interesantes son: cantidad de nuevos usuarios, número de usuarios que regresaron a usar la aplicación, monetización y retención de usuarios. Además de las métricas pre-definidas, el desarrollador puede implementar métricas personalizadas dentro del código de su aplicación. Un punto importante de este servicio es que así como todos los otros, AWS no tiene acceso a sus datos por lo que no son agregados ni consolidados, ni publicados. Todos los datos recolectados y enviados para Amazon Mobile Analytics son 100% de su propiedad.
Caso de Estudio
Creemos que la mejor forma de entender la arquitectura MBaaS es a través de un ejemplo práctico. Teniendo esto en mente, desarrollamos un mini-administrador de contenido con clientes web y dispositivos móviles. En el, el administrador luego de ser autenticado vía Cognito, puede registrar productos que tenga interés en vender y el sistema es responsable por crear canales de divulgación de estos productos – aplicación Android y página web-. Los principales medios de uso y funcionalidades de la aplicación son:
- BackOffice – Área donde el administrador de la tienda, previamente autenticado, puede registrar categorías e ítems. En el proceso de incluir un nuevo ítem es necesario agregar informaciones como nombre, fabricante, valor, observaciones, etc. También es posible cargar una foto del producto. El administrador debe realizar este procedimiento para cada ítem que tenga interés en vender y por último, el podrá volver esas informaciones disponibles para el público general (potenciales compradores) a través de la funcionalidad de publicar. Es en este momento que el backend genera las versiones de la tienda como página web y vuelve visibles las informaciones para la aplicación Android.
- Tienda web y aplicación para usuario anónimo – Esta segunda parte está compuesta por un web site público y una aplicación Android donde son exhibidos los ítems y categorías previamente publicados por el administrador. Aquí los usuarios no registrados pueden navegar por las categorías y detalles de los ítems (incluyendo fotos). También es posible realizar búsquedas de producto por palabra clave.
- Tienda web y aplicación para usuario autenticado – Además de todas las funcionalidades que los usuarios no autenticados tienen acceso, los usuarios autenticados pueden adicionar productos a una lista de favoritos y listar todos los productos que fueron categorizados como tal. Importante reforzar que como estas informaciones de productos favoritos también quedan almacenadas en Amazon Cognito, los usuarios tendrán sus datos sincronizados con otros dispositivos y plataformas en el caso que también realicen login en estas versiones de la aplicación.
- Consola Amazon Mobile Analytics – Dentro de la Consola de Administración de AWS, el administrador de la tienda tiene acceso al panel de visualización con las métricas de datos enviados para Amazon Mobile Analytics.
Vea en seguida algunos prints de pantalla de nuestro administrador de contenido en funcionamiento.
Arquitectura
Ahora vamos a detallar cómo estructuramos las soluciones de AWS para implementarlo. De a poco serán presentados los componentes que hacen parte de la arquitectura, así como la forma en que ellos se integran a medida que revisamos los módulos y funcionalidades descritos anteriormente.
BackOffice
La interfaz de backoffice es un sitio estático hospedado en Amazon S3 que contiene el SDK para JavaScript de AWS en su código fuente. Entenderemos mejor el papel del SDK de esta estructura más adelante, pero es importante entender que el código JavaScript es ejecutado en el navegador de donde el administrador de la tienda está accediendo el backoffice.
También fue utilizado Amazon CloudFront como forma de mejorar la experiencia de usuario en términos de performance de tiempo de carda de la página. Por último, tenemos también Amazon Route 53 para la resolución de DNS y administración de nuestro dominio en Internet. La imagen abajo ilustra este primer paso de composición de la arquitectura:
Necesitamos ahora usar un sistema de autenticación para garantizar que solamente el administrador podrá editar el contenido de la tienda. Para este fin, usamos Amazon Cognito y asociamos permisos con la identidad de administrador que se registró en el sistema usando las credenciales de acceso de Facebook.
Una vez autenticado, el administrador puede hacer la creación o edición del contenido de la tienda. Estas operaciones de edición van a ser implementadas como una API usando Amazon API Gateway. Esto permite tener mucho más control, visibilidad, seguridad y escalabilidad. Los principales métodos para la edición del contenido son:
- Carga de la imagen del ítem – Existen dos lugares donde la imagen del producto aparece: en la pantalla de lista de producto y otra en la pantalla de detalle de producto. Sin embargo, el administrador de la tienda es obligado a realizar un upload de solamente una imagen en nuestro administrador de contenido (la imagen de mayor calidad que es usada en la pantalla de detalle del producto). Queda a cargo del sistema redimensionar esta imagen para que ella sea también usada en la pantalla de lista de productos. Este proceso es realizado vía una llamada de API, que a su vez, ejecuta una función en AWS Lambda, responsable por crear el thumbnail de la imagen y guardar esta nueva imagen de vuelta en Amazon S3. Esta llamada de API es realizada a través del SDK para JavaScript de AWS que comentamos anteriormente. Vea en seguida una ilustración de este flujo:
- Registro de una categoría o ítem – Cada vez que el administrador registra una categoría o ítem con sus respectivas informaciones, los datos son ingresados en Amazon DynamoDB. Esta inserción en la tabla de Amazon DynamoDB también sigue el mismo flujo de proceso anterior: AWS SDK para JavaScript realiza una llamada a Amazon API Gateway, que ejecuta una función AWS Lambda responsable por el CRUD (Create, Read, Update y Delete) de datos en la tabla de Amazon DynamoDB. La imagen en seguida ilustra la arquitectura considerando este nuevo flujo:
- Publicación – Una vez que los datos de productos y categorías fueron registradas o actualizadas, el administrador debe publicar las alteraciones para que las mismas se tornen públicas para el público general. Al seleccionar la opción “Publish”, el sistema llama uno de los servicios expuestos en Amazon API Gateway que a su vez, ejecuta una función AWS Lambda que genera los archivos estáticos (HTMLs y JSONs) basados en las informaciones que fueron registradas en Amazon DynamoDB y utilizando las imágenes que fueron registradas en el paso anterior. La imagen abajo ilustra la arquitectura contemplando todas las funcionalidades de BackOffice:
Tienda
El canal de divulgación de los productos de la tienda está compuesto por un sitio estático (que fue generado durante la publicación del contenido de Backoffice) y una aplicación Android. La tienda sigue una estructura similar a la página inicial del BackOffice: archivos hospedados como sitio estático en Amazon S3; Amazon CloudFront para distribuir el contenido; Amazon Route 53 para la administración del dominio y el SDK de JavaScript para implementar llamadas de recursos AWS como por ejemplo, el mecanismo de búsqueda de productos por palabra clave. Ya la aplicación móvil es básicamente dependiente de las informaciones de los JSONs y las imágenes publicadas en Amazon S3 (y distribuidas a través de Amazon CloudFront). Vea en seguida la estructura de la arquitectura de la tienda en este primer momento:
Como fue dicho anteriormente, el sistema permite que una vez autenticado, los usuarios tengan acceso a registrar productos en la lista de favoritos y visualizar la misma. El proceso de autenticación es hecho usando Amazon Cognito, asociado con la identidad del usuario en Facebook y cada vez que el usuario marca o desmarca el producto como favorito, la información es almacenada en Amazon Cognito Data Store de forma que queda disponible en caso que ese usuario acceda la aplicación en otro dispositivo o plataforma. La estructura para soportar nuestra tienda se ilustra abajo:
Cuando el usuario cambia alguna configuración en sus favoritos, es necesario notificar los dispositivos de este usuario sobre dicho cambio para que las aplicaciones sincronicen las informaciones con el Cognito Data Store actual. Eso puede ser implementado usando Amazon SNS, más específicamente a través de la funcionalidad de Mobile Push. La imagen abajo ilustra la inclusión de este componente de push en la arquitectura:
Por último, usamos AWS Mobile Analytics para monitorear cómo los usuarios están utilizando la aplicación. La imagen en seguida contempla la arquitectura del backend de la tienda con todos los componentes envueltos:
Implementación
Seleccionamos algunos segmentos de código para demostrar el funcionamiento del AWS SDK para JavaScript y Android en la práctica. Estos ejemplos cubren casos de uso de Cognito, API Gateway, Lambda, DynamoDB, CloudSearch y Mobile Analytics. A partir de estos ejemplos, es posible implementar todas las otras funcionalidades de nuestra aplicación de ejemplo.
Login integrado con Facebook
El código de BackOffice que hace la integración con Cognito para implementar el login usando las credenciales de Facebook:
Login de BackOffice integrado con Cognito
function awsAuth(response) {
// The parameters required to intialize the Cognito Credentials object.
var params = {
AccountId: "{{aws_account_id}}",
RoleArn: "{{aws_role_arn}}",
IdentityPoolId: "{{aws_identity_pool_id}}",
Logins: {
'graph.facebook.com': response.authResponse.accessToken
}
};
// initialize the Credentials object with our parameters
AWS.config.region = '{{aws_cognito_region}}';
AWS.config.credentials = new AWS.CognitoIdentityCredentials(params);
AWS.config.credentials.get(
function(err) {
if (!err) {
console.log("Cognito Identity Id: " + AWS.config.credentials.identityId);
}
}
);
...
}
Registro de categoría y producto
Este es el punto donde el código de BackOffice hace la inserción de las informaciones en DynamoDB. Este proceso es realizado vía un llamado del servicio publicado en API Gateway que hace la inserción de los datos en DynamoDB:
Llamado en la API para registro de categoría
function addCategory() {
...
var catName = $("#addCategoryName").val();
var xhr = new XMLHttpRequest();
xhr.open("POST",
"https://YOUR_API_ENDPOINT.execute-api.us-east-1.amazonaws.com/DEPLOY/API_NAME",
true);
xhr.send("{\"categoryName\":\""+catName+"\"}");
}
Función Lambda que escribe la nueva categoría en DynamoDB
...
exports.handler = function(event, context) {
var tableName = "pairarchitecture_categories";
var item = {
"category_id" : {
“S" : '1'
},
"category_name" : {
"S" : event.categoryName
}
};
dynamodb.putItem({
TableName : tableName,
Item : item
}, function(err, data) {
if (err) {
...
} else {
...
context.succeed('SUCCESS');
}
});
}
...
Publicación de contenido
Después del registro de categorías y productos, el próximo paso para ponerlos disponibles para el público general es publicar las alteraciones. Este proceso es realizado también vía un servicio expuesto en API Gateway que ejecuta una función Lambda que realiza todo el proceso de generar los archivos estáticos (HTMLs y JSONs) de la tienda.
Llamado en la API para publicación del contenido editado
function publishItems() {
...
var xhr = new XMLHttpRequest();
xhr.open("POST",
"https://YOUR_API_ENDPOINT.execute-api.us-east-1.amazonaws.com/DEPLOY/API_NAME",
true);
xhr.send("{\"key1\":\"" + timestamp + "\"}");
...
}
Búsqueda de productos
Como fue mencionado anteriormente, los clientes pueden realizar la búsqueda de productos por palabra clave. Aquí está un ejemplo de código que puede ser usado en la aplicación Android para tener acceso a CloudSearch
Buscar de productos por palabra clave del aplicativo Android
private void doSearch(String queryStr) {
try {
new CloudSearchLoader(context).execute(CloudSearchURL +
URLEncoder.encode(queryStr, "UTF-8"));
} catch (Exception e) {
e.printStackTrace();
}
}
Mobile Analytics
El último ejemplo que seleccionamos fue la integración de la aplicación Android con Mobile Analytics. Para eso, solo se debe adicionar llamadas para el producto en cada uno de los métodos del ciclo de vida de la activity – onCreate, onPause, onResume. Para hacer un rastreo de la monetización de la aplicación u otros tipos de eventos, consulte la documentación de producto aquí: (http://amzn.to/1PjAkt8).
Envió de datos a Mobile Analytics
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
…
try {
analytics = MobileAnalyticsManager.getOrCreateInstance(
this.getApplicationContext(),
«{{app_id}}»,
«{{mobile_analytics_identity_pool_id}}»
);
} catch(InitializationException ex) {
…
}
}
@Override
protected void onPause() {
super.onPause();
if(analytics != null) {
analytics.getSessionClient().pauseSession();
//Attempt to send any events that have been recorded to the Mobile Analytics service.
analytics.getEventClient().submitEvents();
}
}
@Override
protected void onResume() {
super.onResume();
if(analytics != null) {
analytics.getSessionClient().resumeSession();
}
}
Conclusión
El patrón de arquitectura presentado en este documento, muestra los grandes beneficios, al hacer uso de servicios administrados para estructurar recursos de backend que soportan aplicaciones para dispositivos móviles. A medida que el trabajo para mantener alta disponibilidad de los servicios, escalar la capacidad de acuerdo con la demanda y adaptarse en respuesta a fallas de componentes de infraestructura, es realizado de forma transparente por las soluciones AWS que utilizamos, el desarrollador puede minimizar los costos de operaciones y concentrarse en innovar en su aplicación con más agilidad. Por último, vale reforzar que además de las soluciones enfocadas en el desarrollo del backend, AWS también posee una serie de productos para ayudar en el proceso de desarrollo de la aplicación (client side) como por ejemplo, AWS Device Farm (para autorización y mejora de pruebas) https://thinkwithwp.com/device-farm/ y AWS Mobile Hub (suite que simplifica / automatiza varios aspectos del desarrollo de aplicaciones para dispositivos móviles y configuración de recursos AWS que los soportan https://thinkwithwp.com/mobile/.