This package provides the core rate limiting implementation that can be used in any context (HTTP, gRPC, or custom applications).
Location: trellis.tech/trellis/common.v3/middleware/ratelimit
Purpose: Generic rate limiting implementation
This is the core rate limiting package. It provides:
Limiter interface - Defines rate limiting behaviorTokenBucketLimiter - Token bucket algorithm implementationKeyExtractor - Key extraction functionsConfig - Rate limiter configurationimport (
"time"
"google.golang.org/grpc"
"trellis.tech/trellis/common.v3/middleware/ratelimit"
)
// Create rate limiter
config := ratelimit.NewConfig(100, time.Second)
limiter := ratelimit.NewTokenBucketLimiter(config)
// Create key extractor
keyExtractor := ratelimit.NewKeyExtractor(ratelimit.KeyTypeIP, nil)
// Add interceptors
server := grpc.NewServer(
grpc.UnaryInterceptor(ratelimit.UnaryRateLimitInterceptor(limiter, keyExtractor)),
grpc.StreamInterceptor(ratelimit.StreamRateLimitInterceptor(limiter, keyExtractor)),
)
For distributed rate limiting across multiple instances:
import (
"context"
"time"
"github.com/redis/go-redis/v9"
"trellis.tech/trellis/common.v3/middleware/ratelimit"
)
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
})
config := ratelimit.NewConfig(100, time.Second)
limiter := ratelimit.NewRedisLimiter(rdb, config)
allowed, err := limiter.Allow(ctx, "user-key")
if !allowed {
// Handle rate limit exceeded
}
You can also use this package directly for custom rate limiting needs:
import (
"context"
"time"
"trellis.tech/trellis/common.v3/middleware/ratelimit"
)
// Create rate limiter
config := ratelimit.NewConfig(100, time.Second)
limiter := ratelimit.NewTokenBucketLimiter(config)
// Check rate limit
allowed, err := limiter.Allow(ctx, "user-key")
if !allowed {
// Handle rate limit exceeded
}
KeyTypeIP: Rate limit by client IP addressKeyTypeUserID: Rate limit by user ID (from context)KeyTypePath: Rate limit by request pathKeyTypeIPPath: Rate limit by IP + path combinationKeyTypeUserPath: Rate limit by user ID + path combinationKeyTypeCustom: Use custom extractor functionimport (
"context"
"fmt"
"trellis.tech/trellis/common.v3/middleware/ratelimit"
)
customExtractor := func(ctx context.Context) string {
// Extract custom key from context
if value := ctx.Value("custom_key"); value != nil {
return fmt.Sprintf("%v", value)
}
return "default"
}
keyExtractor := ratelimit.NewKeyExtractor(ratelimit.KeyTypeCustom, customExtractor)
Configure rate limiting programmatically:
import (
"time"
"trellis.tech/trellis/common.v3/middleware/ratelimit"
)
config := ratelimit.NewConfig(100, time.Second)
config.Burst = 150
limiter := ratelimit.NewTokenBucketLimiter(config)