Frontend Web
Tecnologias Utilizadas
O frontend web tem como base os seguintes frameworks JavaScript:
-
React, como alicerce da arquitetura -
Next.js, para estrutura geral da aplicação SPA (Single Page Application) -
PrimeReact, como suite de componentes de UI -
PrimeFlex, para tema, layouts e estilos padronizados -
PrimeIcons, complemento de ícones do PrimeReact -
FontAwesome free, catálogo de ícones amplamente usado -
Normalize, reset de CSS -
Cloudsupport for React, que oferece componentes estruturais
Os apps de frontend web utilizam como dependência a biblioteca Node react-cloudsupport,
que inclui módulos e componentes para aumentar produtividade dos desenvolvedores bem como auxiliar
o cumprimento dos padrões e convenções de código definidos ao longo deste manual. Dessa forma o
código-fonte dos projetos fica enxuto e o desenvolvedor poderá focar naquilo que lhe é
útil: construir as páginas.
Considere o exemplo cloudsupport-archetype-frontweb como ponto de partida para novos
projetos bem como para acompanhar a leitura deste manual e melhor assimilar os conceitos.
Observação: A biblioteca react-cloudsupport não é restrita ao Next.js e PrimeReact. Conforme a necessidade
do projeto, outros frameworks podem ser utilizados, como por exemplo a suite de componentes
de UI Mantine ou PatternFly. O Next.js e PrimeReact são indicados para aplicações de uso geral e serão
considerados nas seções seguintes.
Funcionalidades da Arquitetura
São funcionalidades oferecidas pela biblioteca Cloudsupport for React:
-
Módulo que oferece uma solução de profile configurável em runtime, em que as propriedades por ambiente podem ser definidas após o build da aplicação, como, por exemplo, no momento da execução do container Docker.
-
Hook
useProfilepara acesso ao profile. -
Componente que exibe aviso de que a aplicação tem atualização pendente, quando há mudanças no profile.
-
Integração OIDC, com suporte a todos os tokens (JWT, Refresh Token, ID Token e User Info), através de extensões e pré-configuração do framework
React OIDC Context. -
Componente
AuthRequiredpara proteger páginas que requerem autenticação via SSO OIDC. -
Injeção automática do Access Token (JWT) nos requests webservice, o que permite autenticar de maneira transparente as requisições para o backend.
-
Injeção automática de parâmetro nas requisições webservice que permite ao backend identificar a origem das requisições (nome e versão da aplicação de frontend).
-
Rotina automática de refresh do Access Token (JWT), de forma a desonerar o desenvolvedor do esforço de manter a autenticação OIDC viva.
-
Fluxo de redirect de pós login, que faz retorno para a página onde o usuário estava antes da autenticação, preservando-se os parâmetros iniciais de URL.
-
Fluxo de redirect de pós logout, em que o OIDC redireciona o usuário para uma página de “sessão encerrada” da aplicação.
-
Módulo para propagação de logout para todas as abas do browser.
-
Componente React integrado ao OIDC que exibe aviso de sessão expirada.
-
Hook
useAuthpara simplificar o acesso aos dados do usuário autenticado em qualquer página/componente. -
Suporte a execução em “Modo Desenvolvedor”, que permite login fake do OIDC (mock do
useAuth) com base em propriedades locais do profile, evitando necessidade de um servidor OIDC IdP local. -
Hook
useToastque fornece Toast global para que qualquer página/componente possa emitir mensagens. -
Hook
useProcessingque fornece API para exibição de indicador de processamento (notifyStart()enotifyStop()), acessível em qualquer página/componente, com suporte a tratamento de requisições concorrentes. -
Suporte a timeout de request webservice via
Networking.fetch(), que estende ofetchdo JavaScript. -
Componentes de UI complementares ao PrimeReact (
ErrorMessage,Field,LoadingBar,RefreshingIcon,RowExpansionBox, etc).- Para aplicações móveis, a biblioteca da Arquitetura
Cloudsupport for React Nativefornece uma suite ampla de componentes de interface gráfica, que inclui tipografia, formulários, validações, imagens, popups, menus, efeitos, etc.
- Para aplicações móveis, a biblioteca da Arquitetura
Estrutura de Camadas
Os apps de frontend web possuem as seguintes camadas:
-
Camada de Apresentação(Pages), engloba os componentes que representam as páginas web. -
Camada de Integração(Remotes), módulos que fazem a comunicação com serviços externos, i.e., que consome os webservices dos microsserviços de backend. -
Camada de Negócio(Services), composta por funcionalidades de negócio providas no próprio frontend web.
A camada de negócio em aplicações de frontend web tende a ser pequena ou mesmo inexistir, pois as regras de negócio são providas tipicamente pelo backend. Ela existe, por exemplo, em aplicações web que precisam oferecer funcionalidades de maneira offline utilizando o banco de dados local do browser. Ressalta-se que as regras de negócio implementadas no frontend web são passíveis, sem muito esforço, de violação, pois o código pode ser alterado pelo usuário final. É importante que todas as regras sejam sempre validadas quando enviadas para o backend. A camada de negócio em frontend web não será escopo deste manual, em razão de sua relevância reduzida, conforme mencionado.
Estrutura de Arquivos
Os apps de frontend web possuem a seguinte estrutura de pastas e arquivos:
package.json
public/
app/
O arquivo package.json é o descritor Node do projeto. Nele é configurado o uso da
biblioteca react-cloudsupport e frameworks associados, como o Next.js e PrimeReact.
A pasta public é definida pelo Next.js. Seu conteúdo sugerido é:
| Item | Descrição |
|---|---|
| favicon/ | Pasta com os arquivos de favicon para Android, iOS e web. |
| resources/ | Pasta com os resources que forem necessários (imagens, scripts, CSS). |
| profile.json | Arquivo tratado pela biblioteca react-cloudsupport que contém as propriedades da aplicação. |
O profile.json será ajustado em tempo de execução conforme as configurações de cada ambiente, como
o de teste, homologação ou produção.
A pasta app contém o código-fonte de aplicação em aderência aos padrões do App Router do
Next.js. A estrutura sugerida para esta pasta é:
| Item | Descrição |
|---|---|
| (pages) | Camada de apresentanção; Contém os componentes de página web. |
| remotes | Camada de funcionalidades remotas; Contém os módulos para comunicação com os microsserviços de backend. |
| services | Camada de negócio; Contém os componentes que implementam regras de negócio, se for o caso. |
| components | Contém componentes compartilhados para uso em páginas web. |
| util | Contém módulos com funções estáticas utilitárias. |
| favicon.ico | Arquivo principal de favicon. |
Neste manual, o termo “componente” usualmente faz referência a componente React. O termo “módulo” faz referência a qualquer módulo JavaScript, que pode exportar constantes, objetos, funções e componentes. Cabe destacar que um componente React é também uma função, porém destinada a uso na interface gráfica, conforme ciclo de vida do React.
Diretrizes Gerais
-
Utilizar preferencialmente JavaScript puro, em conformidade com ECMAScript 6 (ES6), podendo, se for necessidade do projeto, considerar TypeScript. Este manual incluirá diretrizes e exemplos sempre baseados em JavaScript.
-
Utilizar a solução App Router do framework Next.js para organização dos componentes de página e tratamento de roteamento (navegação).
-
Preferir que funções e códigos assíncronos sejam implementados por meio de Promises em lugar da sintaxe
async/await. -
Declarar componentes React na forma de componentes funcionais por meio da construção de funções JavaScript e uso dos Hooks. O React não recomenda a utilização de classes e orientação a objetos.
-
Evitar os operadores padrões de (des)igualdade
==e!=devido à complexidade da semântica IsLooselyEqual do JavaScript/TypeScript. Considerar os operadores estritos===ou!==e verificar explicitamente peloundefinede pelonullsempre que for o caso.Os operadores padrões são desencorajados devido às suas “ambiguidades” lógicas, como esta exemplificada a seguir:
a = "" b = null a == true // retorna false b == true // retorna false b == a // retorna falseSobre loose equality: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness#loose_equality_using
-
Evitar usar o operador
||para efeito de “coalesce” ou valor padrão. Considerar??, que é o verdadeiro Nullish coalescing operator.Exemplos:
// retorna "default" se var1 for qualquer valor Falsy (exemplo: a="" ou a=0) var1 || "default" // retorna "default" se e somente se var1 for null ou undefined var1 ?? "default" -
Evitar implicit coercion.
Em vez de:
if (a) { // ... }fazer:
if (a !== null && a !== undefined) { // ... } -
Atenção aos valores Falsy no JavaScript (convertidos para false em contextos Boolean):
false,0,-0,0n,"",null,undefineeNaN.Evitar implicit coercion e os operadores
==,!=e||(para fins de valor padrão) mitiga substancialmente os problemas causados pelos valores Falsy no JavaScript. -
Não utilizar a sintaxe antiga de módulos do
Node.js, o sistema CommonJS, a citar o comandorequire()e a variável globalmodule.exports. Considere o padrão atual, com as diretivasimporteexport. -
Identar o código preferencialmente com 4 espaços e evitar o caractere de tabulação
\t.
Convenções de Nomes
São convenções de nomes recomendadas:
| Elemento | Regra |
|---|---|
| Pasta | CamelCase iniciando em minúsculo. |
| Arquivo | CamelCase iniciando em minúsculo. |
| Variáveis JavaScript | CamelCase iniciando em minúsculo. |
| Constantes JavaScript | Em maiúsculo, com termos separados por _. |
| Componentes React | CamelCase iniciando em maiúsculo. |
| Funções JavaScript (excetuando Componentes React) | CamelCase iniciando em minúsculo. |
Propriedades por Ambiente
A arquitetura fornece uma solução de profile, que permite definir as propriedades da aplicação por ambiente, como, por exemplo, ambiente local, teste / homologação ou produção. O profile é carregado em tempo de execução, ou seja, seria possível utilizar a mesma imagem Docker em qualquer ambiente.
As propriedades são definidas no arquivo public/profile.json e podem ser complementadas por
JSON definido na variável de ambiente CLOUDSUPPORT_PROFILE do sistema operacional.
O profile pode ser utilizado livremente pelo desenvolvedor para definir variáveis que devem ser ajustadas conforme o ambiente de execução.
Exemplo de profile:
{
"endpointPagamento": "https://gateway.dominio.com/api",
"chaveAcessoIntegrador": "1A938BC02F19DCCD029D94"
}
Recomenda-se evitar a parametrização da aplicação em tempo de compilação (por scripts de build-time), pois nesse caso haverá necessidade de gerar imagens Docker distintas para cada ambiente.
As propriedades são acessíveis pelo Hook useProfile():
const profile = useProfile();
profile.endpointPagamento; // Retorna "https://gateway.dominio.com/api"
O carregamento das propriedades de profile ocorre a partir do endpoint /.well-known/profile.json.
Esse endpoint pode ser mapeado no arquivo next.config.js do Next.js. O projeto do arquétipo
exemplifica a configuração.
Aviso de Atualização
A biblioteca Cloudsupport for React inclui uma funcionalidade que permite emitir aviso
para o usuário de que há atualização pendente. O aviso por padrão é um banner do topo da página, que inclui
opção para o usuário aplicar a atualização.
Exemplo:

Cabe recordar que aplicações em React são SPA (Single Page Application), tal que uma vez carregadas no browser, o usuário fará a navegação entre todas as páginas de maneira virtual, ou seja, o browser não fará a aquisição das páginas junto ao servidor web durante a navegação. Isso ocorre porque o código-fonte React (JavaScript) já foi carregado.
Se não houver um tratamento em nível de arquitetura para detecção de que o servidor web possui uma nova versão do frontend, o usuário poderá permanecer muito tempo navegando nas páginas de uma aplicação defasada, até que ocorra um refresh real ou abertura de nova janela/aba do navegador.
A biblioteca possui um componente interno que monitora o profile, verificando periodicamente se há mudança
no retorno do endpoint /.well-known/profile.json, como, por exemplo, mudança na propriedade appVersion
do profile. Ocorrendo mudança, o componente emite sinal de que a aplicação precisa ser atualizada.
Note que o processo de implantação de nova versão do frontend no ambiente de produção deve
garantir que algum campo do profile seja atualizado. Sugere-se o campo appVersion. O projeto
de arquétipo possui um exemplo de Deployment para Kubernetes com script que injeta automaticamente o
appVersion no profile de acordo com a tag da imagem Docker no momento da subida do Pod/container.
Próximos Passos
As seções Apresentação e Integração explanam sobre como desenvolver páginas web e como realizar a comunicação com o backend. A seção Configuração mostra como habilitar e configurar a arquitetura. Por sim, a seção Documentação da API contém a referência completa de todos os módulos e componentes da arquitetura.