ctxcache(context caching middleware)
Thread-safe context caching for HTTP requests, enabling efficient data sharing within request lifecycles without repeated computations or database queries.
The ctxcache module provides thread-safe context caching for HTTP requests, enabling efficient data sharing within request lifecycles without repeated computations or database queries.
Features
- Thread-safe caching using sync.Map for concurrent access
- Generic type support with compile-time type safety
- Context-based lifecycle - cache lives within request context
- Key existence checking with HasKey function
- Zero-value handling for missing keys
- Any key type support - strings, structs, or custom types
Basic Usage
Initialize ctxcache as your first middleware (recommended for frameworks like Gin):
1func InitRouter() {
2 srv := gin.Default()
3
4 // Initialize context cache first
5 srv.Use(func(c *gin.Context) {
6 ctx := ctxcache.Init(c.Request.Context())
7 c.Request = c.Request.WithContext(ctx)
8 c.Next()
9 })
10
11 // Other middlewares follow
12 // srv.Use(CORS())
13 // srv.Use(Auth())
14}
Storing and Retrieving Data
1// Store different types of data
2ctxcache.Store(ctx, "user_id", int64(12345))
3ctxcache.Store(ctx, "user_name", "john_doe")
4ctxcache.Store(ctx, "is_admin", true)
5
6// Store complex structures
7type User struct {
8 ID int64 `json:"id"`
9 Name string `json:"name"`
10}
11user := User{ID: 123, Name: "John"}
12ctxcache.Store(ctx, "current_user", user)
13
14// Retrieve with type safety
15userID, ok := ctxcache.Get[int64](ctx, "user_id")
16if !ok {
17 // Handle missing key
18 return errors.New("user_id not found in cache")
19}
20
21userName, ok := ctxcache.Get[string](ctx, "user_name")
22if ok {
23 fmt.Printf("User: %s (ID: %d)\n", userName, userID)
24}
25
26// Retrieve complex structures
27cachedUser, ok := ctxcache.Get[User](ctx, "current_user")
28if ok {
29 fmt.Printf("Current user: %+v\n", cachedUser)
30}
Advanced Usage
1// Using custom key types for better organization
2type CacheKey struct {
3 Module string
4 ID int64
5}
6
7userKey := CacheKey{Module: "user", ID: 123}
8ctxcache.Store(ctx, userKey, userData)
9
10// Check if key exists before retrieval
11if ctxcache.HasKey(ctx, userKey) {
12 user, _ := ctxcache.Get[User](ctx, userKey)
13 // Process user data
14}
15
16// Cache expensive operations
17func GetUserPermissions(ctx context.Context, userID int64) ([]string, error) {
18 cacheKey := fmt.Sprintf("permissions_%d", userID)
19
20 // Check cache first
21 if permissions, ok := ctxcache.Get[[]string](ctx, cacheKey); ok {
22 return permissions, nil
23 }
24
25 // Expensive database query
26 permissions, err := database.GetUserPermissions(userID)
27 if err != nil {
28 return nil, err
29 }
30
31 // Cache the result
32 ctxcache.Store(ctx, cacheKey, permissions)
33 return permissions, nil
34}