Help us shape the future of Go! Take the 2026 Go Developer Survey

ratelimit

package
v0.10.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 6, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package ratelimit provides HTTP rate limiting middleware with support for per-principal and per-application rate limits.

The package supports multiple storage backends (in-memory, Redis) and integrates with Cedar policies for dynamic tier-based rate limiting.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrRateLimitExceeded = errors.New("rate limit exceeded")
	ErrStorageFailure    = errors.New("rate limit storage failure")
)

Common errors returned by the rate limiter.

Functions

func NewRedisClient

func NewRedisClient(cfg *RedisConfig) redis.UniversalClient

NewRedisClient creates a Redis client from configuration.

Types

type CoreAPIResolver

type CoreAPIResolver struct {
	// contains filtered or unexported fields
}

CoreAPIResolver adapts coreapi.PolicyStore to the LimitResolver interface. It looks up rate limit policies based on the OAuth client ID from JWT claims.

func NewCoreAPIResolver

func NewCoreAPIResolver(store coreapi.PolicyStore, opts ...CoreAPIResolverOption) *CoreAPIResolver

NewCoreAPIResolver creates a LimitResolver that uses coreapi.PolicyStore.

func (*CoreAPIResolver) GetPolicyForRequest

func (r *CoreAPIResolver) GetPolicyForRequest(ctx context.Context, req *http.Request) *coreapi.RateLimitPolicy

GetPolicyForRequest returns the policy that would be applied to a request. Useful for debugging and displaying policy info in responses.

func (*CoreAPIResolver) InvalidateCache

func (r *CoreAPIResolver) InvalidateCache(clientID string)

InvalidateCache clears the policy cache.

func (*CoreAPIResolver) Resolve

func (r *CoreAPIResolver) Resolve(ctx context.Context, key string, req *http.Request) Limit

Resolve implements LimitResolver by looking up the policy for the OAuth client.

type CoreAPIResolverOption

type CoreAPIResolverOption func(*CoreAPIResolver)

CoreAPIResolverOption configures a CoreAPIResolver.

func WithResolverCache

func WithResolverCache(ttl time.Duration) CoreAPIResolverOption

WithResolverCache enables caching of policy lookups.

type KeyFunc

type KeyFunc func(r *http.Request) string

KeyFunc extracts the rate limit key from a request. Common implementations include extracting principal ID or client ID from JWT.

func ClientEndpointKey

func ClientEndpointKey() KeyFunc

ClientEndpointKey is a convenience function combining ClientKey with EndpointKey.

func ClientKey

func ClientKey() KeyFunc

ClientKey returns a KeyFunc that extracts the OAuth client ID (azp) from JWT claims. Falls back to IP address if no client ID is present.

func CompositeKey

func CompositeKey() KeyFunc

CompositeKey returns a KeyFunc that combines principal and client IDs. Format: "pid:{principal_id}:client:{client_id}" or fallback to IP.

func EndpointKey

func EndpointKey(inner KeyFunc) KeyFunc

EndpointKey wraps another KeyFunc to add endpoint-specific rate limiting. Format: "{inner_key}:path:{path}:method:{method}"

func IPKey

func IPKey() KeyFunc

IPKey returns a KeyFunc that uses the client's IP address.

func PrincipalEndpointKey

func PrincipalEndpointKey() KeyFunc

PrincipalEndpointKey is a convenience function combining PrincipalKey with EndpointKey.

func PrincipalKey

func PrincipalKey() KeyFunc

PrincipalKey returns a KeyFunc that extracts the principal ID from JWT claims. Falls back to IP address if no principal is authenticated.

type Limit

type Limit struct {
	// Rate is the number of requests allowed per Period.
	Rate int

	// Period is the time window for the rate limit (e.g., time.Minute).
	Period time.Duration

	// Burst is the maximum number of requests allowed in a single burst.
	// If zero, defaults to Rate.
	Burst int
}

Limit defines rate limit parameters.

func DefaultLimit

func DefaultLimit() Limit

DefaultLimit returns a sensible default rate limit (100 requests per minute).

func PerHour

func PerHour(n int) Limit

PerHour creates a rate limit of n requests per hour.

func PerMinute

func PerMinute(n int) Limit

PerMinute creates a rate limit of n requests per minute.

func PerSecond

func PerSecond(n int) Limit

PerSecond creates a rate limit of n requests per second.

type LimitResolver

type LimitResolver interface {
	// Resolve returns the rate limit for the given key and context.
	// The key is typically derived from the principal ID or client ID.
	Resolve(ctx context.Context, key string, r *http.Request) Limit
}

LimitResolver determines the rate limit for a given request. This allows dynamic rate limiting based on user tier, endpoint, etc.

type Limiter

type Limiter struct {
	// contains filtered or unexported fields
}

Limiter is the main rate limiter type.

func New

func New(storage Storage, opts ...Option) *Limiter

New creates a new Limiter with the given storage and options.

func (*Limiter) Allow

func (l *Limiter) Allow(r *http.Request) (Result, error)

Allow checks if a request should be allowed.

func (*Limiter) Close

func (l *Limiter) Close() error

Close releases resources held by the limiter.

func (*Limiter) Middleware

func (l *Limiter) Middleware() func(http.Handler) http.Handler

Middleware returns an HTTP middleware that enforces rate limits.

type MemoryOption

type MemoryOption func(*MemoryStorage)

MemoryOption configures MemoryStorage.

func WithCleanupInterval

func WithCleanupInterval(d time.Duration) MemoryOption

WithCleanupInterval sets the interval for cleaning up expired windows.

type MemoryStorage

type MemoryStorage struct {
	// contains filtered or unexported fields
}

MemoryStorage is an in-memory rate limit storage using sliding window algorithm. Suitable for single-instance deployments and development/testing.

func NewMemoryStorage

func NewMemoryStorage(opts ...MemoryOption) *MemoryStorage

NewMemoryStorage creates a new in-memory rate limit storage.

func (*MemoryStorage) Allow

func (m *MemoryStorage) Allow(ctx context.Context, key string, limit Limit) (Result, error)

Allow implements Storage.Allow using a sliding window algorithm.

func (*MemoryStorage) Close

func (m *MemoryStorage) Close() error

Close implements Storage.Close.

func (*MemoryStorage) Reset

func (m *MemoryStorage) Reset(ctx context.Context, key string) error

Reset implements Storage.Reset.

type Option

type Option func(*Limiter)

Option configures a Limiter.

func WithKeyFunc

func WithKeyFunc(keyFunc KeyFunc) Option

WithKeyFunc sets the function to extract rate limit keys from requests.

func WithLimit

func WithLimit(limit Limit) Option

WithLimit sets a static rate limit.

func WithObservability

func WithObservability(obs *observability.Observability) Option

WithObservability sets the observability provider for metrics and tracing.

func WithResolver

func WithResolver(resolver LimitResolver) Option

WithResolver sets a custom limit resolver.

type RedisConfig

type RedisConfig struct {
	// Addr is the Redis server address (e.g., "localhost:6379").
	Addr string

	// Password is the Redis password (optional).
	Password string

	// DB is the Redis database number (default 0).
	DB int

	// PoolSize is the maximum number of connections (default 10).
	PoolSize int

	// Cluster enables Redis Cluster mode.
	Cluster bool

	// ClusterAddrs are the cluster node addresses (used when Cluster is true).
	ClusterAddrs []string
}

RedisConfig contains configuration for connecting to Redis.

type RedisOption

type RedisOption func(*RedisStorage)

RedisOption configures RedisStorage.

func WithKeyPrefix

func WithKeyPrefix(prefix string) RedisOption

WithKeyPrefix sets a prefix for all rate limit keys in Redis.

type RedisStorage

type RedisStorage struct {
	// contains filtered or unexported fields
}

RedisStorage is a Redis-backed rate limit storage using sliding window algorithm. Suitable for distributed deployments where multiple instances share rate limit state.

func NewRedisStorage

func NewRedisStorage(client redis.UniversalClient, opts ...RedisOption) *RedisStorage

NewRedisStorage creates a new Redis-backed rate limit storage. The client can be *redis.Client, *redis.ClusterClient, or any UniversalClient.

func (*RedisStorage) Allow

func (r *RedisStorage) Allow(ctx context.Context, key string, limit Limit) (Result, error)

Allow implements Storage.Allow using a sliding window algorithm with Redis.

func (*RedisStorage) Close

func (r *RedisStorage) Close() error

Close implements Storage.Close. Note: This does NOT close the Redis client since it may be shared.

func (*RedisStorage) Reset

func (r *RedisStorage) Reset(ctx context.Context, key string) error

Reset implements Storage.Reset.

type Result

type Result struct {
	// Allowed is true if the request should be permitted.
	Allowed bool

	// Remaining is the number of requests remaining in the current window.
	Remaining int

	// ResetAt is when the rate limit window resets.
	ResetAt time.Time

	// RetryAfter is the duration to wait before retrying (only set if not allowed).
	RetryAfter time.Duration
}

Result contains the outcome of a rate limit check.

type StaticResolver

type StaticResolver struct {
	Limit Limit
}

StaticResolver always returns the same limit.

func (*StaticResolver) Resolve

func (s *StaticResolver) Resolve(ctx context.Context, key string, r *http.Request) Limit

Resolve implements LimitResolver.

type Storage

type Storage interface {
	// Allow checks if a request should be allowed and updates the counter.
	// Returns the result of the check and any error.
	Allow(ctx context.Context, key string, limit Limit) (Result, error)

	// Reset clears the rate limit state for a key.
	Reset(ctx context.Context, key string) error

	// Close releases any resources held by the storage.
	Close() error
}

Storage defines the interface for rate limit state storage.

type TieredResolver

type TieredResolver struct {
	Tiers    map[string]Limit
	Default  Limit
	TierFunc func(ctx context.Context, key string, r *http.Request) string
	// contains filtered or unexported fields
}

TieredResolver returns different limits based on tier.

func (*TieredResolver) Resolve

func (t *TieredResolver) Resolve(ctx context.Context, key string, r *http.Request) Limit

Resolve implements LimitResolver.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL