APIs e Microsserviços

5 mai, 2016

Mobile Backend as a Service – Padrão de Arquitetura

Publicidade

Mobile Backend as a Service, ou simplesmente MBaaS, é um modelo de arquitetura onde recursos de backend que suportam aplicações móveis são provisionados e operados como serviço gerenciado. Nesse modelo, todos os detalhes internos para manter alta disponibilidade dos serviços, escalar a capacidade de acordo com a demanda e adaptar-se em resposta a falhas de componentes de infraestrutura são realizados de forma transparente pela AWS. Ao liberar a equipe técnica de todo o trabalho de manter a infraestrutura de operações, as empresas podem dedicar mais tempo e esforço nos aspectos que mais diferenciam sua aplicação das outras existentes, como criação de novas funcionalidades, interfaces e detalhes na usabilidade. Além disso, o modelo permite uma fácil reutilização de componentes do backend, porque eles geralmente contam com APIs para uma fácil integração com outros módulos da mesma aplicação (exemplo: interface web) ou até mesmo aplicações distintas que necessitam do mesmo serviço.

Estudo de caso

Acreditamos que a melhor forma para entender a arquitetura MBaaS é por meio 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) por meio 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 a 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 essas 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:

Figura1

Figura 1 – Telas de login e cadastro de produto

Figura2

Figura 2 – Telas principais da loja web e aplicativo Android

Arquitetura

Agora vamos detalhar como estruturamos as soluções da AWS para implementá-las. 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 as funcionalidades descritos na seção anterior.

BackOffice

A interface do backoffice é 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 dessa estrutura mais adiante, mas é importante entender que o código JavaScript é executado no navegador de onde o administrador da loja está acessando o backoffice.

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:

Figura3

Figura 3 – BackOffice site estático

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.

Figura4

Figura 4 – BackOffice autenticação Cognito

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, o administrador da loja é requisitado a 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 essa 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 essa nova imagem de volta no Amazon S3. Essa chamada de API é realizada pelo AWS SDK para JavaScript que comentamos anteriormente. Veja abaixo uma ilustração desse fluxo:

Figura5

Figura 5 – BackOffice upload de imagem do produto

  • 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 realizada 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 esse novo fluxo:

Figura6

Figura 6 – BackOffice cadastro de categorias ou itens

  • 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 elas 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:

Figura7

Figura 7 – BackOffice versão final

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 à da 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 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:

Figura8

Figura 8 – Estrutura do backend da loja web e aplicativo Android

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:

Figura9

Figura 9 – Loja com suporte para seleção de produtos favoritos

Quando o usuário muda alguma configuração em seus favoritos, é necessário notificar os dispositivos desse 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 por meio da funcionalidade de Mobile Push. A imagem abaixo ilustra a inclusão desse componente de push na arquitetura:

Figura10

Figura 10 – Loja para dispositivo móvel com suporte para atualização via push

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:

Figura11

Figura 11 – Backend loja versão final

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 deles, é 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 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.

@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. À medida que o trabalho para manter alta disponibilidade dos serviços escalar a capacidade de acordo com a demanda e adaptar-se em resposta a 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 possui uma série de produtos que visam a auxiliar no processo de desenvolvimento do aplicativo (client side), como AWS Device Farm (para automatização e melhoria de cobertura de testes) 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).

***

Artigo escrito por Henry Alvarado, com a colaboração de Heitor Vidal.

Este artigo faz parte do AWSHUB, rede de profissionais AWS gerenciado pelo iMasters.