Simplificando a manutenção de seus projetos Front-End

Rafael Antonio Lucio
easynvest-engineers
6 min readAug 30, 2018

Comumente os projetos front-end pelos lugares onde passei costumavam ser projetos grandes, com diversos fluxos de negócio dentro de uma única aplicação chamada “Portal” ou “CMS”. Estes projetos são complexos, e torna muito difícil qualquer atualização ou até mesmo a evolução tecnológica da aplicação (sabemos que no universo front-end a evolução acontece constantemente).

Hoje sabemos que existe a necessidade de construir aplicações front-end em larga escala que sejam fáceis de manter e que nos permita inovar dentro deste mesmo projeto. 🤔😥

Vamos imaginar o seguinte cenário abaixo:

— Seu time começa a desenvolver uma plataforma de e-commerce grande e você junto ao time decide utilizar um determinado framework para agilizar o desenvolvimento da plataforma, porém, passa-se algum tempo é lançada uma nova versão do framework e pra ajudar é uma versão de breaking change 😥

Pensando em uma aplicação monolítica você possui apenas duas alternativas, não atualizar o framework ou refatorar todos os pontos onde aquela determinada atualização afeta no projeto.

Em alguns casos dependendo do projeto, você não pode refatorar o sistema, pois não possui tempo hábil para executar esta demanda, o que acaba gerando um débito técnico grande no projeto, pois, dado que não é possível refatorar, você irá fazer a outra metade do projeto incluindo novos débitos técnicos. 😥

Para resolver este problema, levamos os projetos front-end para um modelo bem próximo ao dos micro serviços, criando várias aplicações e utilizando o conceito de composição, começamos a compor nossas aplicações tornando-a como se fosse uma única aplicação. 🤔

Para fazer isso, primeiro de tudo precisávamos entender como separar nossas aplicações, nos baseamos no conceito de bounded context.

Bounded Context

Bounded context é um padrão central no DDD (Domain-Driven Design), o foco do DDD esta na sessão de design estratégico que trata de grandes modelos e times. O DDD lida com grandes modelos dividindo-os em diferentes contextos limitados e sendo explícito sobre suas inter-relações.

Descrito por Martin Fowler neste post.

O bounded context possui conceitos não relacionados (como um ticket de suporte existente apenas em um contexto de suporte ao cliente), mas também compartilham conceitos como produtos e clientes.

O DDD segue descrevendo diversas de maneiras pelas quais você tem relações entre os contextos limitados.

Vou utilizar como referência nosso portal da Easynvest, para podermos enxergar os diversos contextos.

Autenticação/Autorização do usuário e recuperação de senha, já é autoexplicativo, compreende o login, esqueci minha senha e nova senha, credenciais do usuário, controle de acesso, permissões de operação, etc.

Tela de autenticação portal da Easynvest

Cadastro do usuário, compreende todo fluxo de preenchimento de informações cadastrais até a criação da conta do cliente, para que o cliente fique dentro das normativas de compliance.

Tela de abertura de conta portal da Easynvest

Prateleiras de produtos financeiros, compreende a exibição dos produtos fornecidos pela Easynvest— Tesouro Direto, CDB, LC, LF, LCI, LCA, Fundos de investimento e Ações

Tela de exibição dos produtos portal da Easynvest

Para saber mais sobre os produtos, você pode clicar neste link ou baixar o aplicativo aqui.

Acompanhamento dos produtos que foram comprados, o que chamamos de “custódia”, compreende a exibição dos títulos financeiros que foram adquiridos pelo cliente, nos mostra sua rentabilidade nos últimos 30 dias e o valor do rendimento em cada produto.

Tela para acompanhar meus investimentos portal da Easynvest

Atualização de dados cadastrais do usuário, compreende dados profissionais, pessoais, residenciais, renda financeira, etc.

Tela com menu Perfil ativo portal da Easynvest

Financeiro, compreende Movimentação financeira, Extrato, Imposto de Renda, etc.

Tela com menu Finanças ativo portal da Easynvest

Dentro de cada um destes seis contextos existem outros N contextos para atender as regras de negócio.

Ao me juntar com o time tínhamos duas opções:

1- Nós poderíamos criar uma única aplicação, que teria todas as interfaces exibidas acima (o que é comumente feito), porém, teríamos muitos problemas para evoluir a plataforma.

2- Fazer uma aplicação para cada contexto de negócio, desta forma teríamos diversas aplicações relativamente pequenas, o que tornaria mais simples a manutenção, a evolução das aplicações e o refactoring.

Optamos pela segunda opção!

Ok, agora iríamos construir N aplicações e, com certeza, apareceriam outros problemas. Os dois principais problemas que identificamos foram:

1- Como as aplicações se comunicariam?

Será que eu precisarei fazer um login para cada aplicação? Afinal o usuário precisa estar autenticado para consumir os serviços back-end!

2- Como criar componentes reutilizáveis para todas estas aplicações e que sejam fáceis para que todos os times possam utilizar?

Para resolver o problema de comunicação pensamos em uma aplicação que ficará responsável por fazer o proxy reverso para todos as outras aplicações exemplo:

Arquitetura da infraestrutura de cloud das aplicações client

A imagem acima nos mostra que os usuários chegam até o site da Easynvest através da AWS utilizando um serviço de balanceamento, no nosso o ELB que logo em seguida manda a carga para um nosso cluster Kubernetes que por sua vez orquestra os containers dentro do cluster.

O container BOOTSTRAP é o responsável por fazer o proxy reverso para as demais aplicações, ou seja, quando um usuário digita na barra de endereço do navegador a url https://www.easynvest.com.br/autenticacao é a bootstrap quem sabe pra qual container irá redirecionar o usuário, neste caso ele irá para o container de autenticação.

A bootstrap também tem uma outra função muito importante que é fazer o proxy reverso para as APIs do back-end, no nosso caso os serviços de back-end não estão no mesmo cluster.

Percebam que até o momento não falamos sobre as tecnologias que serão utilizadas no front end, pois isso não é muito relevante, cada aplicação pode ser criada com uma tecnologia diferente e todas elas podem conviver juntas.

No nosso caso na Easynvest, nosso site era escrito em ASP.MVC e front-end em Angularjs, já o portal em sua grande maioria é escrito utilizando React.

As aplicações podem ser escritas uma em React, outra em Elm, outra em Vue, outra em Angular, esta decisão vai depender do problema que queremos resolver.

Observação: esta abordagem chega muito próximo ao conceito de micro frontend citado neste site https://micro-frontends.org, no nosso caso não estamos falando de diversas tecnologia convivendo juntas em uma mesma aplicação, mas, são aplicações diferentes.

O conceito de micro frontend chega ao nível de features diferentes na mesma aplicação escrita em diferentes linguagens convivendo juntas até mesmo na mesma view como a imagem abaixo:

Imagem ilustrativa sobre micro-frontends

Não sabemos se queremos chegar a esse nível, estamos estudando para continuar propondo as soluções mais eficientes.

Conclusão

Seguindo esta abordagem:

  • Agnóstico a tecnologia.
  • Isolamento claro do time, o que facilita o entendimento do negócio.
  • Cada time é responsável pelo seu contexto de negócio, exemplo: Time de cadastro, Time de vendas, etc.
  • Aplicações relativamente pequenas, o que torna a manutenção mais simples e ágil.
  • Qualquer integrante novo no time com pouco tempo pode se adaptar rapidamente ao projeto.
  • Deploys independentes, não corremos o risco de afetar outra aplicação, o que da mais segurança e confiabilidade ao publicar uma nova feature ou um hotfix, bugfix, etc.
  • Facilita a evolução da plataforma.
  • Motiva o time a buscar cada dia mais inovação e novas formas de resolver os problemas do negócio.
  • O time se sente mais motivado o que reduz a busca por oportunidades de inovação no mercado, pois você possui flexibilidade para inovar.
  • A plataforma fica em um processo de constante atualização e evolução.

--

--