Aula 18 - Gestão de Estado de Aplicação Full Stack e Caching Distribuído 🌐
Objetivo Pedagógico
Objetivo: Arquitetura de sincronização de estado entre cliente e servidor com TanStack Query (React Query), cache distribuído com Redis e invalidação por tags.
📑 1. Fundamentos Teóricos & Análise Técnica
Em aplicações Full Stack modernas, a gestão de dados transita entre duas realidades distintas: o Estado do Servidor (Server State) e o Estado do Cliente (Client State). Confundir esses dois estados em uma única store global gera dados obsoletos (stale data), problemas de sincronização e perda de performance.
A solução arquitetural de ponta divide a responsabilidade: 1. No Servidor: Implementação do padrão Cache-Aside com Redis, onde requisições frequentes de leitura consultam a memória em cache antes de tocar o banco relacional. Mutações invalidam chaves ou tags de cache correspondentes de forma atômica. 2. No Cliente: Utilização de bibliotecas de sincronização como TanStack Query (React Query). Ela atua como um coordenador inteligente que gerencia deduplicação de requisições, refetch em background quando a janela ganha foco (Window Focus Refetching), atualizações otimistas (Optimistic Updates) e expiração de dados (Stale Time).
📐 Arquitetura Conceitual & Diagrama de Fluxo
graph TD
Client["SPA Frontend (TanStack Query)"] -->|Cache-First: staleTime 60s| ClientCache["Cache de Memória no Navegador"]
ClientCache -->|Se Dados Obsoletos: Fetch| Gateway["API Gateway / Backend"]
Gateway --> Redis["Redis Cache (Cache-Aside)"]
Redis -->|Cache Hit| Gateway
Redis -->|Cache Miss| SQL["PostgreSQL / MySQL"]
SQL --> Redis
style Client fill:#e1f5fe,stroke:#01579b
style ClientCache fill:#e8f5e9,stroke:#2e7d32
style Gateway fill:#fff3e0,stroke:#e65100
style Redis fill:#f3e5f5,stroke:#7b1fa2 🔍 Pilares e Diretrizes Técnicas
Nesta unidade, aprofundamos os seguintes conceitos fundamentais: - Padrão Cache-Aside: O backend busca primeiro no cache rápido; se ausente, lê do banco e popula o cache. - Atualizações Otimistas (Optimistic Updates): A UI reflete a alteração do usuário instantaneamente antes da resposta do servidor, revertendo apenas em caso de erro. - Invalidação de Cache por Tags: Purga seletiva de coleções inteiras no Redis quando uma entidade é criada ou atualizada. - Deduplicação de Requisições: Múltiplos componentes solicitando o mesmo recurso acionam apenas uma requisição HTTP.
🛠️ 2. Implementação Prática em Arquitetura Full Stack e Cache Distribuído
Abaixo está a implementação técnica de referência, estruturada com padrões de engenharia de software e foco em robustez:
// optimistic-mutation.ts (Atualização Otimista com TanStack Query)
import { useMutation, useQueryClient } from '@tanstack/react-query';
interface Task { id: string; title: string; completed: boolean; }
export function useToggleTask() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (task: Task) => {
const res = await fetch(`/api/tasks/${task.id}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ completed: !task.completed })
});
if (!res.ok) throw new Error('Falha ao atualizar tarefa.');
return res.json();
},
// Atualização Otimista: altera a tela antes da resposta da API!
onMutate: async (updatedTask) => {
await queryClient.cancelQueries({ queryKey: ['tasks'] });
const previousTasks = queryClient.getQueryData<Task[]>(['tasks']);
queryClient.setQueryData<Task[]>(['tasks'], (old = []) =>
old.map(t => t.id === updatedTask.id ? { ...t, completed: !t.completed } : t)
);
return { previousTasks };
},
// Se falhar, reverte para o estado anterior
onError: (err, task, context) => {
if (context?.previousTasks) {
queryClient.setQueryData(['tasks'], context.previousTasks);
}
},
// Invalida e sincroniza com o servidor
onSettled: () => {
queryClient.invalidateQueries({ queryKey: ['tasks'] });
}
});
}
💡 Análise Passo a Passo do Código
- onMutate Imediato: Aplica a alteração diretamente no cache local do cliente, proporcionando sensação de resposta instantânea.
- onError Rollback: Se o servidor retornar erro 500, a lista é restaurada exatamente para o estado anterior.
- onSettled Sincronização: Garante que o estado local seja alinhado com a resposta definitiva do banco de dados.
🎯 3. Próximos Passos & Sequência Didática
-
Slides da Aula
-
Quiz de Fixação
-
Exercícios Práticos
-
Desafio de Projeto