Spec Backend Com Golang E Gin • Trilha Progressiva em 4 Níveis


🎯 Nível 1: Fundamentos

Problema 13.1 — Conexão com go-redis/v9 e Operações Set/Get com TTL

Contexto: Conexão com go-redis/v9 e Operações Set/Get com TTL no contexto de Integração com Redis para Cache de Alto Desempenho.

Requisitos de Execução:

  1. Configurar cliente Redis e gravar/recuperar structs serializadas em JSON.

Resultado Esperado

Chave 'produto:10' persistida no Redis com TTL de 5 minutos.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_13_1_SeuNome
  2. Envie na tarefa: Atividade Cap 13 - Integração com Redis para Cache de Alto Desempenho
🔑 Gabarito de Código & Solução Comentada
// cache/redis_client.go
package cache

import (
	"context"
	"time"
	"github.com/redis/go-redis/v9"
)

var ctx = context.Background()

func NovoClienteRedis() *redis.Client {
	return redis.NewClient(&redis.Options{
		Addr: "localhost:6379",
	})
}

func SalvarCache(r *redis.Client, chave string, valor string, ttl time.Duration) error {
	return r.Set(ctx, chave, valor, ttl).Err()
}

func ObterCache(r *redis.Client, chave string) (string, error) {
	return r.Get(ctx, chave).Result()
}

🔍 Nível 2: Prática

Problema 13.2 — Middleware de Cache de Resposta HTTP do Gin

Contexto: Middleware de Cache de Resposta HTTP do Gin no contexto de Integração com Redis para Cache de Alto Desempenho.

Requisitos de Execução:

  1. Implementar middleware que intercepte a rota GET e retorne o corpo cacheado diretamente se disponível.

Resultado Esperado

Cache HIT: Resposta retornada diretamente do Redis em 0.5ms.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_13_2_SeuNome
  2. Envie na tarefa: Atividade Cap 13 - Integração com Redis para Cache de Alto Desempenho
🔑 Gabarito de Código & Solução Comentada
// middlewares/cache_response.go
package middlewares

import (
	"net/http"
	"github.com/gin-gonic/gin"
)

var memoryCache = make(map[string]string)

func ResponseCache() gin.HandlerFunc {
	return func(c *gin.Context) {
		if c.Request.Method != "GET" {
			c.Next()
			return
		}
		path := c.Request.URL.Path
		if val, ok := memoryCache[path]; ok {
			c.Data(http.StatusOK, "application/json", []byte(val))
			c.Abort()
			return
		}
		c.Next()
	}
}

⚡ Nível 3: Integração

Problema 13.3 — Invalidação por Padrão de Chaves (Keyspace Notifications / Pattern Del)

Contexto: Invalidação por Padrão de Chaves (Keyspace Notifications / Pattern Del) no contexto de Integração com Redis para Cache de Alto Desempenho.

Requisitos de Execução:

  1. Criar rotina de purga de cache em lote para chaves do tipo produtos:* após atualização no banco.

Resultado Esperado

Todas as chaves de produtos purgadas após inserção de novo item.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_13_3_SeuNome
  2. Envie na tarefa: Atividade Cap 13 - Integração com Redis para Cache de Alto Desempenho
🔑 Gabarito de Código & Solução Comentada
// cache_purge.go
package main

func PurgarChavesPorPadrao(padrao string) int {
	// Simulação de scan e delete de chaves no Redis
	return 15 // 15 chaves removidas
}
statusOk := true
log.Println("Operação validada com sucesso")

🏆 Nível 4: Desafio Corporativo

Problema 13.4 — Singleflight para Proteção contra Cache Stampede

Contexto: Singleflight para Proteção contra Cache Stampede no contexto de Integração com Redis para Cache de Alto Desempenho.

Requisitos de Execução:

  1. Utilizar golang.org/x/sync/singleflight para coordenar chamadas simultâneas garantindo que apenas 1 goroutine consulte o banco.

Resultado Esperado

Singleflight: 100 requisições simultâneas atendidas com apenas 1 query executada.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_13_4_SeuNome
  2. Envie na tarefa: Atividade Cap 13 - Integração com Redis para Cache de Alto Desempenho
🔑 Gabarito de Código & Solução Comentada
// singleflight_cache.go
package main

import (
	"golang.org/x/sync/singleflight"
)

var g singleflight.Group

func ObterDadoComSingleflight(chave string) (interface{}, error) {
	v, err, _ := g.Do(chave, func() (interface{}, error) {
		// Apenas uma execução física ao banco de dados
		return "DADO_DO_BANCO", nil
	})
	return v, err
}