Desacoplamento da camada de Visualização do Backend usando BFF
Imagem: CBSI.net
O uso de APIs e Microserviços auxiliou e também acelerou na adoção de outros padrões de integração e apresentação de dados, mas, também criou algumas complexidades para quem necessita apresentar dados ou interagir com o cliente usando camadas de apresentação com experiências ricas, mas o desafio ainda continua. Como diminuir o acoplamento entre camadas do meu software, nesse caso focado na camada de visualização e o backend?
Frameworks para desenvolvimento Frontend x Componentes Nativos de Backend
Por muito tempo, desenvolvemos usando HTML, CSS e Java Script puramente e muitas vezes, mesmo usando o já citado MVC, acabamos usando componentes nativos da nossa linguagem de backend no nosso frontend.
Quem trabalhou com Java já deve ter usado Taglibs, JSTL, componentes JSF ou mesmo hoje, ainda temos as Template Engines para quem trabalha com o Spring MVC (visto que o Spring é um dos frameworks mais modernos e usados para desenvolvimento Java).
Mesmo efetuando um bom trabalho de Engenharia de Software, definir classes bem estruturadas e backend bem desenhado, acabamos por adicionar um nível de acoplamento usando esses componentes nativos de linguagens backend. Não que essa abordagem esteja totalmente errada, visto que muitas vezes, o que precisamos para um software executar em menor escala, é da simplicidade da sua arquitetura e reutilização de seus componentes para uma melhor manutenção e implementação.
Mas, se a necessidade já se expande para um padrão Omnichannel, onde não importa qual o dispositivo nosso cliente vai acessar meu software, se eu desejo manter a escalabilidade e ter o mínimo ou quase chegar a zero o meu acoplamento, nosso projeto precisa ser desenhado já pensando em frameworks de Frontend, como Angular, Vue, React, etc.
Imagem: webmediums.com
Usando esse tipo de abordagem, separamos de vez o que é camada de apresentação (visto que alguns frameworks também são responsivo, ou seja, se adaptando ao dispositivo que vai renderizar esse frontend) em um deploy e o nosso backend, onde realmente toda a regra de negócio está desenvolvida e onde eu realmente consigo fazer deploy sem impactar alguns pontos da minha aplicação (caso eu opte por seguir um caminho de APIs e Microserviços).
Mas ainda assim, existe um ponto de acoplamento, visto que, se eu usar uma página HTML para acessar uma API que expõem dados, mesmo que pensando na abordagem API First, podemos ter problemas de agregamento de dados ou mesmo forçar nosso HTML a ter uma regra de exibição e disponibilização de dados que não queremos. Existem situações em que não é um padrão muito sustentável forçar processamento no lado do frontend e é isso que o padrão BFF tenta sanar.
O que é o BFF?
BFF significa Backend for Front-end e podemos definir como uma camada de abstração entre o frontend e backend do projeto.
Vamos supor que nosso sistema precisa ser acessado por aplicativo móvel ou por tela de computador, porém, dependendo do dispositivo, a experiência e talvez até funcionalidades serão limitadas ou não estarão presentes a todos os dispositivos (um requisito definido pelos stakeholders). Veja que só essa situação já nos força a ter um processamento do lado do frontend e ambos usarem a mesma API de backend.
Porém, se usarmos uma camada acima da API ou Microserviços do nosso backend, podemos repassar esse processamento e mesmo aplicação da regra de negócio e deixar que o retorno do mesmo seja o mais transparente e amigável para o frontend. É nesse ponto que nosso BFF entra. O BFF pode ser uma API, que recebe a requisição do nosso frontend, um ponto comum de entrada de requisições que, dependendo da regra de negócio a ser processada, acessa uma API ou um conjunto de Microserviços necessários para retornar e formatar a requisição e montagem de tela do nosso frontend.
Imagem: akfpartners.com
O BFF é comumente usado para esse trabalho de receber requisição e tratar o retorno para o frontend. Lembrando que as regras de negócio aplicadas a um BFF são mais simples que as regras de negócio a serem desenvolvidas no Backend. Não é indicado processamentos pesados no BFF, visto que essa função é feita pelos microserviços ou APIs expostas. Aqui entra um conceito do SOLID que é o conceito de responsabilidade única, onde o BFF deve conter somente regras para tratar a requisição e auxiliar o BFF e regras de negócio para o real funcionamento do software devem ser distribuídos entre seus microserviços.
Quando eu devo usar e quando eu não devo usar o BFF?
O BFF deve ser usado sempre que houver necessidade de tratamento da devolutiva de uma requisição e ajudar a evitar processamento na exibição de dados no frontend. Um tratamento de dados ou uma padronização de informações é o melhor uso de BFF.
Porém, aqui cabe sempre uma reflexão, que, eu posso ter mais de uma API no padrão BFF e isso pode ser definido caso a caso e projeto a projeto.
Agora, se a sua situação é mais simples, seu software necessidade de uma menor capacidade de processamento, o seu cenário não precisa de deploys separados de camadas ou mesmo, você sabe que seu software vai ser acessado exclusivamente de um dispositivo, creio que vale a pena pensar em um design mais simples como um MVC com um controller melhor estruturado. Porém essas decisões devem ser tomadas conforme a estrutura do time e também o nível de maturidade de desenvolvimento.
Existe também uma alternativa, caso você não deseje usar APIs Rest no seu projeto, é o uso de GraphQL, que funciona como um “API Aggregator" porém usando uma outra abordagem na hora de se conectar a outros microserviços, para agregar e montar exibição de dados para o frontend, porém, não irei abordar com mais detalhes o GraphQL aqui, pois, apesar de poder fazer a mesma função que o BFF, sua implementação é bem diferente, porém, precisamos sempre pesquisar e estarmos atentos a outras alternativas para o design do nosso software.
Informação Adicional
O Padrão BFF foi criado por Sam Newman, baseado sua experiência com o aplicativo Soundcloud (um app de músicas que pode ser acessado tanto via mobile, dispositivos inteligentes e computadores) e que dependendo de onde o mesmo era acessado, as funcionalidades podem sofrer alguma modificação na sua apresentação.
Para mais informações, vou deixar aqui o link do site do Sam Newman onde ele aborda de forma mais profunda o padrão arquitetural BFF: https://samnewman.io/patterns/architectural/bff/
Também quero deixar o link referente ao API Composition, um padrão de agregação de APIs a serem chamadas a partir de uma API acima da sua camada, onde o mesmo pode ser chamado de API Aggregator: https://microservices.io/patterns/data/api-composition.html.
Este artigo foi escrito por Adriano Mota e publicado originalmente em Prensa.li.