Pitch: Construí o Interceptor HTTP Definitivo para Angular: 6 Padrões de Resiliência e RxJS na Prática
Se você desenvolve aplicações Angular complexas, como sistemas de dashboards dinâmicos com múltiplos widgets ou interfaces baseadas em nós para mapear regras de processos, você sabe que a rede é o ambiente mais hostil do frontend.
Requisições simultâneas disputando a mesma URL, conexões instáveis, lentidão no servidor e o temido erro 401 quebrando dezenas de chamadas paralelas. A abordagem clássica é criar um HttpInterceptor gigante, que rapidamente se torna um "God Object" impossível de manter.
Para resolver isso aplicando os princípios SOLID (focando fortemente no SRP - Princípio da Responsabilidade Única), desenvolvi o ngx-smart-interceptor. Vale ressaltar que este é um projeto experimental e em constante evolução. Estou aprendendo muito durante todo o processo de construção de uma biblioteca do zero, iterando e melhorando a arquitetura a cada novo desafio.
Em vez de processar regras, o interceptor principal atua apenas como um Orquestrador, delegando o trabalho pesado do RxJS para Handlers especialistas. Criei um Sandbox para validar a biblioteca sob estresse, e aqui estão os 6 pilares de resiliência que ela entrega com poucas linhas de configuração.
1. Deduplicação de Requisições (In-Flight Caching)
Em grids complexos, é comum que vários componentes peçam o mesmo dicionário de dados (ex: GET /api/status) ao mesmo tempo. O DeduplicationHandler entra em ação usando o operador shareReplay(1) do RxJS.
Se o seu código disparar 3 requisições simultâneas, apenas uma chamada real vai para a aba Network:
// No seu componente, mesmo se você forçar chamadas simultâneas...
ngOnInit() {
forkJoin({
widgetA: this.http.get('/api/config'),
widgetB: this.http.get('/api/config'),
widgetC: this.http.get('/api/config')
}).subscribe(res => {
// Todos os 3 recebem os dados ao mesmo tempo,
// mas o servidor só recebeu 1 requisição!
console.log(res);
});
}
2. Padrão Circuit Breaker
Se a sua API de inteligência de negócios cair (Erro 500), o frontend não deve metralhar o servidor com retries cegos.
O CircuitBreakerHandler vigia falhas consecutivas. Ao atingir o limite (ex: 3 falhas), ele "desarma" o circuito. Novas requisições são bloqueadas diretamente no navegador (sem ir à rede) e um erro local é retornado instantaneamente, dando tempo para o servidor respirar.
3. Fila Offline (Offline Queue)
Imagine o usuário montando um diagrama complexo e clicando em "Salvar" (POST) justo quando o Wi-Fi cai.
Com a enableOfflineQueue ativa, o interceptor captura a falha de rede. Ele guarda o POST na memória e, assim que o navegador emite o evento online, ele reprocessa a fila silenciosamente em background. Seu usuário nunca perde dados.
4. Adaptive Loading (Carregamento Adaptativo)
O interceptor possui um profiler que percebe quando a conexão está estrangulada (alta latência).
Ele injeta automaticamente o cabeçalho X-Adaptive-Network: slow na requisição. No seu backend (seja Node, C# ou Java), você pode ler esse header e retornar um payload menor para salvar a experiência do usuário:
// Exemplo no Backend (Express.js) consumindo o cabeçalho
app.get('/api/dashboard', (req, res) => {
const isSlowNetwork = req.headers['x-adaptive-network'] === 'slow';
if (isSlowNetwork) {
return res.json(getLightweightData()); // Sem imagens pesadas
}
return res.json(getFullData());
});
5. Observabilidade & Profiler
Se uma chamada de API demorar mais de 3 segundos, o interceptor dispara um alerta de degradação (Slow Request Warning) diretamente no console ou para o seu serviço de monitoramento (como Sentry).
6. Global Hooks e Erros Normalizados
O terror do Angular é lidar com o objeto nativo HttpErrorResponse espalhado pelos componentes. O Orquestrador normaliza os erros e permite a injeção de Global Hooks para lidar com situações críticas (como o erro 401 Unauthorized) em um único lugar.
Veja como é fácil configurar a renovação de Token globalmente:
// app.config.ts
export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(withInterceptors([smartInterceptor])),
provideSmartInterceptor({
generateCorrelationIds: true,
globalHooks: {
// Intercepta TODOS os 401s da aplicação
onUnauthorized: (err, req) => {
console.warn('Sessão expirada. Redirecionando ou renovando token...');
const authService = inject(AuthService);
authService.logout();
}
}
})
]
};
Como fica o código no dia a dia?
A beleza de usar um interceptor inteligente é que o código dos seus componentes fica extremamente limpo.
Você não precisa escrever lógicas complexas de tentativa (retry) ou tratar mensagens de rede obscuras. O interceptor injeta uma userFriendlyMessage e um correlationId para rastreabilidade:
// dashboard.component.ts
salvarFluxo() {
this.http.post('/api/process', this.payload).pipe(
catchError((error) => {
// O interceptor já tratou bloqueios de Circuit Breaker ou falhas de rede.
// O erro chega limpo e padronizado para a interface:
this.toastService.showError(error.userFriendlyMessage);
console.error(`Falha rastreável: ${error.correlationId}`);
return EMPTY;
})
).subscribe(() => {
this.toastService.showSuccess('Fluxo salvo com sucesso!');
});
}
Conclusão
Construir bibliotecas robustas é sobre dominar as ferramentas do ecossistema e aplicar padrões de Engenharia de Software. O ngx-smart-interceptor prova que é possível transformar a caótica camada de rede do frontend em um pipeline previsível, resiliente e altamente testável.
Convido você a testar a biblioteca, ver a documentação completa gerada via Compodoc e analisar a arquitetura do código fonte (que conta com uma esteira automatizada de CI/CD completa).
GitHub: https://github.com/ErickG123/ngx-smart-interceptor
NPM: npm install ngx-smart-interceptor
Se a biblioteca for útil para os seus projetos, considere deixar uma ⭐ no repositório! Toda contribuição e Pull Request da comunidade é super bem-vinda.