Acreditamos que a melhor forma para entender a arquitetura MBaaS é através de um exemplo prático. Tendo isso em mente, desenvolvemos um mini-gerenciador de conteúdo com clientes web e dispositivos móveis. Nele o administrador, depois de autenticado via Cognito, pode cadastrar produtos que tenham interesse em vender e o sistema é responsável por gerar canais de divulgação desses produtos – aplicativo Android e página web. Os principais meios de uso e funcionalidades da aplicação são:
- BackOffice – Área onde o administrador da loja, devidamente autenticado, pode cadastrar categorias e itens. No processo de inclusão de novo item é necessário adicionar informações como nome, fabricante, valor, observação, etc. Também é possível carregar uma foto do produto. O administrador deve realizar esse procedimento para cada item que tenha interesse em vender e, por fim, ele poderá tornar essas informações disponíveis para o público geral (potenciais compradores) através da funcionalidade de publicar loja/alterações. É nesse momento que o backend gera as versões da loja como página web e torna visíveis as informações para o aplicativo Android.
- Loja web e aplicativo para usuário anônimo – Esta segunda parte é composta por um website público e um aplicativo Android onde são exibidos os itens e categorias previamente publicados pelo administrador. Aqui os usuários deslogados poderão navegar pelas categorias e detalhes dos itens (fotos, inclusive). Também é possível realizar buscas de produto por palavra-chave.
- Loja web e aplicativo para usuário autenticado – Além de todas as funcionalidades que os usuários deslogados têm acesso, os usuários autenticados podem adicionar produtos a uma lista de favoritos e listar todos os produtos que foram categorizados como tal. Importante reforçar que, como estas informações de produtos favoritos também ficam armazenadas no Cognito, os usuários terão seus dados sincronizados com outros dispositivos e plataformas caso, claro, realizem login nesses locais.
- Console Amazon Mobile Analytics – Dentro do Console de Gerenciamento da AWS, o administrador da loja tem acesso ao painel de visualização com as métricas de dados enviados para o Amazon Mobile Analytics.
Veja abaixo alguns prints de tela do nosso gerenciador de conteúdo em funcionamento:
Arquitetura
Agora vamos detalhar como estruturamos as soluções da AWS para implementá-lo. Aos poucos, serão apresentados os componentes que fazem parte da arquitetura, bem como a forma em que eles interagem à medida que revisitamos os módulos e funcionalidades descritos na seção anterior.
Back Office
A interface do back office é um site estático hospedado no Amazon S3 que contém o AWS SDK para JavaScript em seu código fonte. Iremos entender melhor o papel do SDK desta estrutura mais adiante, mas é importante entender que o código JavaScript é executado no navegador de onde o administrador da loja está acessando o back office.
Também foi utilizado o CloudFront como forma de melhorar a experiência do usuário em termos de performance de tempo de carga de página. Por fim, temos também o Amazon Route 53 para resolução de DNS e gerenciamento do nosso domínio na Internet. A imagem abaixo ilustra esse primeiro passo de composição da arquitetura:
Precisamos agora usar um sistema de autenticação para garantir que somente o administrador poderá editar o conteúdo da loja. Para esse fim, usamos o Amazon Cognito e associamos permissões com a identidade do administrador que logou no sistema utilizando suas credencias de acesso do Facebook.
Uma vez autenticado, o administrador consegue fazer a criação ou edição do conteúdo da loja. Essas operações de edição vão ser implantadas como uma API usando o Amazon API Gateway. Isso permite ter muito mais controle, visibilidade, segurança e escalabilidade. Os principais métodos para edição de conteúdo são:
- Upload da imagem do item – Existem dois lugares em que a imagem do produto aparece: na tela de listagem de produtos e outra vez na tela de detalhamento de produto. Porém, ao administrador da loja é requisitado fazer upload de somente uma imagem em nosso gerenciador de conteúdo (a imagem de maior qualidade que é usada na tela de detalhamento de produto). Fica a cargo do sistema redimensionar esta imagem para que ela seja também utilizada na tela de listagem de produtos. Esse processo é feito via chamada de API que, por sua vez, executa uma função no AWS Lambda responsável por criar o thumbnail da imagem e salvar esta nova imagem de volta no Amazon S3. Essa chamada de API é realizada através do AWS SDK para JavaScript que comentamos anteriormente. Veja abaixo uma ilustração deste fluxo:
- Cadastro de categoria ou item: cada vez que o administrador cadastra uma categoria ou item com as suas respectivas informações, os dados são inseridos no Amazon DynamoDB. Essa inserção na tabela do DynamoDB também segue o mesmo fluxo do processo anterior: AWS JDK para JavaScript realiza uma chamada para o API Gateway, que executa uma função lambda responsável pelo CRUD (create, read, update e delete) de dados na tabela do DynamoDB. A imagem abaixo ilustra a arquitetura considerando este novo fluxo:
- Publicação: Uma vez que os dados de produtos e categorias foram cadastrados ou atualizados, o administrador deve publicar as alterações para que as mesmas se tornem públicas para o público geral. Ao selecionar a opção “Publicar”, o sistema chama um dos serviços expostos no API Gateway que, por sua vez, executa uma função lambda que gera os arquivos estáticos (HTMLs e JSONs) baseado nas informações que foram cadastradas no DynamoDB e utilizando as imagens que foram cadastradas no passo anterior. A imagem abaixo ilustra a arquitetura contemplando todas as funcionalidades do BackOffice:
Loja
O canal de divulgação dos produtos da loja é composto por um site estático (que foi gerado durante a publicação de conteúdo do BackOffice) e um aplicativo Android. A loja segue uma estrutura semelhante a página inicial do BackOffice: arquivos hospedados como site estático no S3; CloudFront para distribuir o conteúdo; Route53 para gerenciamento de domínio e SDK para JavaScript para implementar chamadas de recursos para AWS como, por exemplo, mecanismo de busca de produtos por palavra chave. Já o aplicativo móvel é basicamente dependente das informações de JSONs e imagens publicadas no S3 (e distribuídas através do CloudFront). Veja abaixo a estrutura da arquitetura da loja neste primeiro momento:
Como dito anteriormente, o sistema permite que, uma vez autenticado, os usuários tenham acesso a inserir produtos na lista de favoritos e visualizar essa lista. O processo de autenticação é feito usando o Amazon Cognito associado com a identidade do usuário no Facebook e para cada vez que o usuário marca ou desmarca o produto como favorito, a informação é armazenada no Cognito Data Store de forma que fica disponível caso esse usuário acesse o aplicativo em outro dispositivo ou plataforma. Agora a estrutura para suportar nossa loja está como a ilustrada abaixo:
Quando o usuário muda alguma configuração em seus favoritos, é necessário notificar os dispositivos deste usuário sobre tal mudança para que os aplicativos sincronizem as informações com o Cognito Data Store atual. Isso pode ser implementado usando o Amazon SNS, mais especificamente através da funcionalidade de Mobile Push. A imagem abaixo ilustra a inclusão deste componente de push na arquitetura:
Por fim, usamos o AWS Mobile Analytics para fazer o monitoramento de como os usuários estão utilizando o aplicativo. A imagem abaixo contempla a arquitetura do backend da loja com todos os componentes envolvidos:
Implementação
Selecionamos alguns trechos de código para demonstrar o funcionamento do AWS SDK para JavaScript e Android na prática. Estes exemplos cobrem casos de uso de Cognito, API Gateway, Lambda, DynamoDB, CloudSearch e Mobile Analytics. A partir destes exemplos, é possível implementar todas as outras funcionalidades da nossa aplicação de exemplo.
Login integrado com Facebook
O código do BackOffice que faz integração com o Cognito para implementar login utilizando credenciais do Facebook é:
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); } } ); … }
Código 01 – Login de BackOffice integrado com Cognito
Cadastro de categoria e produto
Este é o ponto onde o código do BackOffice faz a inserção das informações direto no DynamoDB. Este processo é feito via invocação de serviço publicado no API Gateway que faz a inserção dos dados no DynamoDB.
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+”\”}”); }
Código 02 – Chamado na API para cadastro de categoria
… 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’); } }); } …
Código 03 – Função Lambda que escreve a nova categoria no DynamoDB
Publicação de conteúdo
Após o cadastro de categorias e produtos, o próximo passo para torná-los disponíveis para o público geral é publicar as alterações. Este processo é feito também via serviço exposto no API Gateway que executa uma função lambda que realiza todo o processo de gerar os arquivos estáticos (HTMLs e JSONs) da loja.
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 + “\”}”); … }
Código 04 – Chamado na API para publicação do conteúdo editado
Busca de produtos
Como mencionado anteriormente, os clientes podem realizar busca de produtos por palavra-chave. Aqui está um exemplo de código que pode ser usado no aplicativo Android para fazer acesso ao CloudSearch:
private void doSearch(String queryStr) { try { new CloudSearchLoader(context).execute(CloudSearchURL + URLEncoder.encode(queryStr, “UTF-8″)); } catch (Exception e) { e.printStackTrace(); } }
Código 05 – Buscar de produtos por palavra-chave do aplicativo Android
Mobile Analytics
O último exemplo que selecionamos foi a integração do aplicativo Android com o Mobile Analytics. Para isso, basta adicionar chamadas para o produto em cada um dos métodos de ciclo de vida da sua activity – onCreate, onPause, onResume. Para fazer tracking de monetização da aplicação ou outros tipos de eventos, acesse a documentação do produto (http://amzn.to/1PjAkt8).
@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(); } }
Código 06 – Envio de dados para o Mobile Analytics
Conclusão
O padrão de arquitetura apresentado neste documento demonstra grandes benefícios ao fazer uso de serviços gerenciados para estruturar recursos de backend que suportam aplicações para dispositivos móveis. A medida que o trabalho para manter alta disponibilidade dos serviços, escalar a capacidade de acordo com a demanda e adaptar-se em resposta às falhas de componentes de infraestrutura é realizado de forma transparente pelas soluções AWS que utilizamos, o desenvolvedor consegue minimizar os custos de operações e concentrar-se em inovar seu aplicativo com mais agilidade.
Por fim, vale reforçar que além das soluções focadas no desenvolvimento do backend, a AWS também possui uma série de produtos que visam auxiliar no processo de desenvolvimento do aplicativo (client side) como, por exemplo, AWS Device Farm (para automatização e melhoria de cobertura de testes) https://aws.amazon.com/device-farm/ e AWS Mobile Hub (suíte que simplifica/automatiza vários aspectos do desenvolvimento de aplicativos para dispositivos móveis e configuração de recursos AWS que os suportam) https://aws.amazon.com/mobile/.
***
Artigo escrito por Henry Alvarado.
Este artigo faz parte do AWSHUB, rede de profissionais AWS gerenciado pelo iMasters.