Cache em TypeScript: Redis, Memcached e soluções integradas
Aplicações web modernas em TypeScript exigem alta velocidade de resposta e gerenciamento eficiente de recursos. Uma das ferramentas-chave para atingir esse objetivo é o cache. Neste artigo, vamos detalhar três abordagens principais para cache no ecossistema TypeScript/Node.js: uso de Redis, Memcached e soluções integradas (in-memory cache). Você aprenderá como escolher a ferramenta adequada para sua tarefa e verá exemplos de código funcionais.
Por que precisamos de cache em TypeScript?
O cache permite armazenar temporariamente dados frequentemente solicitados em um armazenamento rápido, para reduzir o tempo de resposta e diminuir a carga em bancos de dados ou APIs externas. Em TypeScript, rodando em Node.js, o cache é especialmente útil para:
- Acelerar consultas repetitivas ao banco de dados;
- Reduzir latências ao acessar serviços externos;
- Otimizar operações computacionalmente complexas;
- Gerenciar sessões de usuários.
Vamos considerar três tipos principais de cache disponíveis para o desenvolvedor em TypeScript.
1. Cache Integrado (In-Memory Cache)
A maneira mais simples e rápida é armazenar dados na memória do próprio processo Node.js. Para isso, pode-se usar Map ou bibliotecas mais avançadas, como node-cache.
Vantagens:
- Velocidade máxima (ausência de chamadas de rede);
- Simplicidade de implementação;
- Não requer instalação de serviços externos.
Desvantagens:
- Os dados são perdidos ao reiniciar a aplicação;
- Limitado pela quantidade de RAM de um único processo;
- Não funciona em modo cluster (cada processo tem seu próprio cache).
Exemplo usando node-cache
Instale a biblioteca:
npm install node-cacheImplementação de um serviço de cache simples:
import NodeCache from 'node-cache';
class MemoryCacheService { private cache: NodeCache;
constructor(ttlSeconds: number = 600) { this.cache = new NodeCache({ stdTTL: ttlSeconds, checkperiod: 120 }); }
public get<T>(key: string): T | undefined { return this.cache.get<T>(key); }
public set<T>(key: string, value: T, ttl?: number): boolean { return this.cache.set(key, value, ttl); }
public has(key: string): boolean { return this.cache.has(key); }
public del(key: string): number { return this.cache.del(key); }
public flush(): void { this.cache.flushAll(); }}
// Usoconst cacheService = new MemoryCacheService(300); // TTL = 5 minutos
async function getData(id: string): Promise<any> { const cached = cacheService.get<any>(`data:${id}`); if (cached) { return cached; }
// Simulação de operação custosa const data = await fetchFromDatabase(id); cacheService.set(`data:${id}`, data); return data;}2. Cache com Redis
Redis é um poderoso armazenamento de dados in-memory, frequentemente usado como cache. Ele suporta estruturas de dados complexas (strings, hashes, listas, conjuntos) e pode operar em modo cluster.
Vantagens:
- Persistência (opcional);
- Suporte a estruturas de dados complexas (ex.: conjuntos ordenados);
- Mecanismos integrados de TTL (Time-To-Live);
- Excelente desempenho (até 100.000 operações/seg);
- Suporte a Pub/Sub para troca de mensagens.
Desvantagens:
- Requer instalação e configuração de um servidor separado;
- Usa mais memória do que soluções integradas;
- Latências de rede (embora mínimas).