Skip to Content

Cache

The cache package provides a unified caching interface with in-memory and Redis backends. It supports TTL-based expiration, cache-aside patterns, and key management utilities.

Import

import "github.com/gofastadev/gofasta/pkg/cache"

Key Types

Cache

The primary caching interface implemented by all cache drivers.

type Cache interface { Get(ctx context.Context, key string, dest interface{}) error Set(ctx context.Context, key string, value interface{}, ttl time.Duration) error Delete(ctx context.Context, key string) error Exists(ctx context.Context, key string) (bool, error) Flush(ctx context.Context) error Close() error }

CacheConfig

type CacheConfig struct { Driver string `yaml:"driver" env:"CACHE_DRIVER"` Host string `yaml:"host" env:"CACHE_HOST"` Port int `yaml:"port" env:"CACHE_PORT"` Password string `yaml:"password" env:"CACHE_PASSWORD"` DB int `yaml:"db" env:"CACHE_DB"` TTL time.Duration `yaml:"ttl" env:"CACHE_TTL"` Prefix string `yaml:"prefix" env:"CACHE_PREFIX"` }

Key Functions

FunctionSignatureDescription
NewMemoryCachefunc NewMemoryCache(cfg CacheConfig) CacheCreates an in-memory cache instance
NewRedisCachefunc NewRedisCache(cfg CacheConfig) (Cache, error)Creates a Redis-backed cache instance
NewCachefunc NewCache(cfg CacheConfig) (Cache, error)Factory function that creates a cache based on the driver config
BuildKeyfunc BuildKey(prefix string, parts ...string) stringConstructs a namespaced cache key

Usage

In-Memory Cache

c := cache.NewMemoryCache(cache.CacheConfig{ TTL: 5 * time.Minute, Prefix: "myapp", }) defer c.Close() // Set a value err := c.Set(ctx, "user:123", user, 10*time.Minute) if err != nil { log.Fatalf("failed to cache: %v", err) } // Retrieve the value var cached User err = c.Get(ctx, "user:123", &cached) if err != nil { log.Println("cache miss") }

Redis Cache

c, err := cache.NewRedisCache(cache.CacheConfig{ Driver: "redis", Host: "localhost", Port: 6379, Password: "", DB: 0, TTL: 15 * time.Minute, Prefix: "myapp", }) if err != nil { log.Fatalf("failed to connect to Redis: %v", err) } defer c.Close() err = c.Set(ctx, "session:abc", sessionData, 30*time.Minute)

Cache-Aside Pattern

func GetUser(ctx context.Context, c cache.Cache, repo UserRepository, id string) (*User, error) { var user User key := cache.BuildKey("users", id) // Try cache first err := c.Get(ctx, key, &user) if err == nil { return &user, nil } // Cache miss -- fetch from database userPtr, err := repo.FindByID(ctx, id) if err != nil { return nil, err } // Populate cache _ = c.Set(ctx, key, userPtr, 10*time.Minute) return userPtr, nil }

Cache Invalidation

// Delete a single key err := c.Delete(ctx, "user:123") // Check existence before fetching exists, err := c.Exists(ctx, "user:123") if exists { // use cached value } // Flush all keys (use with caution) err = c.Flush(ctx)

Configuration via config.yaml

cache: driver: redis host: localhost port: 6379 password: "" db: 0 ttl: 15m prefix: myapp
  • Config — Cache configuration loading
  • Sessions — Redis-backed session storage
  • Resilience — Circuit breakers for cache backends
Last updated on