mirror of
https://github.com/SamyRai/tercul-backend.git
synced 2025-12-27 05:11:34 +00:00
- Add RateLimit, RequestValidation, and CORS middleware. - Configure middleware chain in API server. - Implement Redis cache for GraphQL Automatic Persisted Queries. - Add .golangci.yml and fix linting issues (shadowing, timeouts).
93 lines
2.7 KiB
Go
93 lines
2.7 KiB
Go
package cache
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"time"
|
|
)
|
|
|
|
// Cache defines the interface for caching operations
|
|
type Cache interface {
|
|
// Get retrieves a value from the cache
|
|
Get(ctx context.Context, key string, value interface{}) error
|
|
|
|
// Set stores a value in the cache with an optional expiration
|
|
Set(ctx context.Context, key string, value interface{}, expiration time.Duration) error
|
|
|
|
// Delete removes a value from the cache
|
|
Delete(ctx context.Context, key string) error
|
|
|
|
// Clear removes all values from the cache
|
|
Clear(ctx context.Context) error
|
|
|
|
// GetMulti retrieves multiple values from the cache
|
|
GetMulti(ctx context.Context, keys []string) (map[string][]byte, error)
|
|
|
|
// SetMulti stores multiple values in the cache with an optional expiration
|
|
SetMulti(ctx context.Context, items map[string]interface{}, expiration time.Duration) error
|
|
}
|
|
|
|
// Item represents a cache item with metadata
|
|
type Item struct {
|
|
Key string
|
|
Value interface{}
|
|
Expiration time.Duration
|
|
}
|
|
|
|
// MarshalBinary implements the encoding.BinaryMarshaler interface
|
|
func (i *Item) MarshalBinary() ([]byte, error) {
|
|
return json.Marshal(i.Value)
|
|
}
|
|
|
|
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface
|
|
func (i *Item) UnmarshalBinary(data []byte) error {
|
|
return json.Unmarshal(data, &i.Value)
|
|
}
|
|
|
|
// KeyGenerator generates cache keys for different types of data
|
|
type KeyGenerator interface {
|
|
// EntityKey generates a key for an entity by ID
|
|
EntityKey(entityType string, id uint) string
|
|
|
|
// ListKey generates a key for a list of entities
|
|
ListKey(entityType string, page, pageSize int) string
|
|
|
|
// QueryKey generates a key for a custom query
|
|
QueryKey(entityType, queryName string, params ...interface{}) string
|
|
}
|
|
|
|
// DefaultKeyGenerator implements the KeyGenerator interface
|
|
type DefaultKeyGenerator struct {
|
|
Prefix string
|
|
}
|
|
|
|
// NewDefaultKeyGenerator creates a new DefaultKeyGenerator
|
|
func NewDefaultKeyGenerator(prefix string) *DefaultKeyGenerator {
|
|
if prefix == "" {
|
|
prefix = "tercul:"
|
|
}
|
|
return &DefaultKeyGenerator{
|
|
Prefix: prefix,
|
|
}
|
|
}
|
|
|
|
// EntityKey generates a key for an entity by ID
|
|
func (g *DefaultKeyGenerator) EntityKey(entityType string, id uint) string {
|
|
return g.Prefix + entityType + ":id:" + fmt.Sprintf("%d", id)
|
|
}
|
|
|
|
// ListKey generates a key for a list of entities
|
|
func (g *DefaultKeyGenerator) ListKey(entityType string, page, pageSize int) string {
|
|
return g.Prefix + entityType + ":list:" + fmt.Sprintf("%d:%d", page, pageSize)
|
|
}
|
|
|
|
// QueryKey generates a key for a custom query
|
|
func (g *DefaultKeyGenerator) QueryKey(entityType, queryName string, params ...interface{}) string {
|
|
key := g.Prefix + entityType + ":" + queryName
|
|
for _, param := range params {
|
|
key += ":" + fmt.Sprintf("%v", param)
|
|
}
|
|
return key
|
|
}
|