Redis

Configuracao do Redis com ioredis, Docker, cache, sessoes e integracao automatica com BullMQ.

O Redis e configurado automaticamente pelo PlazerCLI quando voce seleciona features que dependem dele (BullMQ, rate limiting, sessoes) ou quando voce o habilita diretamente. O PlazerCLI usa o ioredis como client por sua robustez, suporte a cluster e reconnect automatico.

O Redis e auto-habilitado quando voce escolhe BullMQ, Rate Limiting ou WebSockets com adapter Redis. Voce nao precisa seleciona-lo manualmente nesses casos.

Docker Compose

O PlazerCLI adiciona o servico Redis ao docker-compose.yml:

# docker-compose.yml
services:
  redis:
    image: redis:7-alpine
    container_name: ${PROJECT_NAME}-redis
    ports:
      - '6379:6379'
    volumes:
      - redis_data:/data
    command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru
    healthcheck:
      test: ['CMD', 'redis-cli', 'ping']
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  redis_data:

Modulo Redis (NestJS)

No NestJS, o PlazerCLI gera um modulo global com provider ioredis:

// apps/api/src/redis/redis.module.ts
import { Global, Module } from '@nestjs/common';
import { RedisService } from './redis.service';

@Global()
@Module({
  providers: [RedisService],
  exports: [RedisService],
})
export class RedisModule {}

// apps/api/src/redis/redis.service.ts
import { Injectable, OnModuleDestroy } from '@nestjs/common';
import Redis from 'ioredis';

@Injectable()
export class RedisService extends Redis implements OnModuleDestroy {
  constructor() {
    super({
      host: process.env.REDIS_HOST || 'localhost',
      port: Number(process.env.REDIS_PORT) || 6379,
      password: process.env.REDIS_PASSWORD || undefined,
      maxRetriesPerRequest: null,
      retryStrategy: (times) => Math.min(times * 50, 2000),
    });
  }

  async onModuleDestroy() {
    await this.quit();
  }
}

Cache helper

O PlazerCLI gera um helper de cache reutilizavel:

// apps/api/src/redis/cache.helper.ts
import { RedisService } from './redis.service';

export class CacheHelper {
  constructor(private readonly redis: RedisService) {}

  async get<T>(key: string): Promise<T | null> {
    const data = await this.redis.get(key);
    return data ? JSON.parse(data) : null;
  }

  async set(key: string, value: unknown, ttlSeconds = 3600): Promise<void> {
    await this.redis.set(key, JSON.stringify(value), 'EX', ttlSeconds);
  }

  async del(key: string): Promise<void> {
    await this.redis.del(key);
  }

  async invalidatePattern(pattern: string): Promise<void> {
    const keys = await this.redis.keys(pattern);
    if (keys.length > 0) {
      await this.redis.del(...keys);
    }
  }
}

// Uso em um service:
@Injectable()
export class UsersService {
  private cache: CacheHelper;

  constructor(private redis: RedisService) {
    this.cache = new CacheHelper(redis);
  }

  async findById(id: string) {
    const cached = await this.cache.get(`user:${id}`);
    if (cached) return cached;

    const user = await this.prisma.user.findUnique({ where: { id } });
    await this.cache.set(`user:${id}`, user, 1800); // 30 min
    return user;
  }
}

Express / Fastify

Nos frameworks Express e Fastify, o Redis e exportado como singleton:

// apps/api/src/lib/redis.ts
import Redis from 'ioredis';

export const redis = new Redis({
  host: process.env.REDIS_HOST || 'localhost',
  port: Number(process.env.REDIS_PORT) || 6379,
  password: process.env.REDIS_PASSWORD || undefined,
  maxRetriesPerRequest: null,
});

redis.on('error', (err) => console.error('Redis error:', err));
redis.on('connect', () => console.log('Redis connected'));

// Uso em qualquer rota:
import { redis } from '../lib/redis';

app.get('/api/products/:id', async (req, res) => {
  const cached = await redis.get(`product:${req.params.id}`);
  if (cached) return res.json(JSON.parse(cached));

  const product = await db.product.findUnique({ where: { id: req.params.id } });
  await redis.set(`product:${req.params.id}`, JSON.stringify(product), 'EX', 3600);
  res.json(product);
});

Variaveis de ambiente

VariavelPadraoDescricao
REDIS_HOSTlocalhostHost do servidor Redis
REDIS_PORT6379Porta do servidor Redis
REDIS_PASSWORD(vazio)Senha do Redis (opcional em dev)