Skip to content

Go Redis Example

2️⃣ Go + Redis (cache-aside example)

Install

go mod init redis-demo
go get github.com/redis/go-redis/v9
go get github.com/gin-gonic/gin

main.go

package main

import (
    "context"
    "encoding/json"
    "log"
    "net/http"
    "time"

    "github.com/gin-gonic/gin"
    "github.com/redis/go-redis/v9"
)

var (
    ctx   = context.Background()
    rdb   *redis.Client
)

type User struct {
    ID   string `json:"id"`
    Name string `json:"name"`
    Role string `json:"role"`
}

func getUserFromDB(id string) (*User, error) {
    log.Println("⏳ Hitting DB for user", id)
    time.Sleep(500 * time.Millisecond) // simulate DB delay
    return &User{ID: id, Name: "User " + id, Role: "admin"}, nil
}

func main() {
    // ---- Redis client ----
    rdb = redis.NewClient(&redis.Options{
        Addr: "localhost:6379",
    })

    if err := rdb.Ping(ctx).Err(); err != nil {
        log.Fatal("Redis connection failed:", err)
    }

    router := gin.Default()

    router.GET("/users/:id", getUserHandler)

    log.Println("Server running on :3000")
    if err := router.Run(":3000"); err != nil {
        log.Fatal(err)
    }
}

func getUserHandler(c *gin.Context) {
    id := c.Param("id")
    cacheKey := "user:" + id

    // 1) try cache
    val, err := rdb.Get(ctx, cacheKey).Result()
    if err == nil {
        log.Println("⚡ Cache hit")
        var u User
        if err := json.Unmarshal([]byte(val), &u); err == nil {
            c.JSON(http.StatusOK, gin.H{"from": "cache", "data": u})
            return
        }
    } else if err != redis.Nil {
        log.Println("Redis error:", err)
    }

    // 2) cache miss → DB
    log.Println("🐢 Cache miss")
    user, err := getUserFromDB(id)
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": "db error"})
        return
    }

    // 3) store in cache with TTL
    data, _ := json.Marshal(user)
    if err := rdb.Set(ctx, cacheKey, data, 60*time.Second).Err(); err != nil {
        log.Println("Redis set error:", err)
    }

    c.JSON(http.StatusOK, gin.H{"from": "db", "data": user})
}