Loading documentation...
Loading documentation...
Loading documentation...
Limits the number of requests per client using a token bucket algorithm.
// 100 requests per second, burst of 10
s.Use(middleware.RateLimit(100, 10))s.Use(middleware.RateLimitWithConfig(middleware.RateLimitConfig{
Rate: 100, // requests per second
Burst: 10, // maximum burst
KeyFunc: func(r *http.Request) string {
// Rate limit by API key instead of IP
return r.Header.Get("X-API-Key")
},
Handler: func(w http.ResponseWriter, r *http.Request) {
// Custom rate limit response
helix.TooManyRequests(w, "Rate limit exceeded")
},
SkipFunc: func(r *http.Request) bool {
// Skip rate limiting for health checks
return r.URL.Path == "/health"
},
CleanupInterval: time.Minute,
ExpirationTime: 5 * time.Minute,
}))X-RateLimit-Limit, X-RateLimit-Remaining, Retry-After)The token bucket algorithm allows:
Example: Rate=100, Burst=10 means:
Default behavior limits by client IP:
s.Use(middleware.RateLimit(100, 10))The middleware extracts the client IP from:
X-Forwarded-For header (first IP)X-Real-IP headerRemoteAddr from requestLimit by API key instead of IP:
s.Use(middleware.RateLimitWithConfig(middleware.RateLimitConfig{
Rate: 100,
Burst: 10,
KeyFunc: func(r *http.Request) string {
return r.Header.Get("X-API-Key")
},
}))Limit by authenticated user:
s.Use(middleware.RateLimitWithConfig(middleware.RateLimitConfig{
Rate: 100,
Burst: 10,
KeyFunc: func(r *http.Request) string {
// Extract user ID from context or header
userID := getUserID(r)
return userID
},
}))s.Use(middleware.RateLimitWithConfig(middleware.RateLimitConfig{
Rate: 100,
Burst: 10,
Handler: func(w http.ResponseWriter, r *http.Request) {
helix.WriteProblem(w, helix.ErrTooManyRequests.WithDetail(
"Rate limit exceeded. Please try again later.",
))
},
}))Skip rate limiting for specific requests:
s.Use(middleware.RateLimitWithConfig(middleware.RateLimitConfig{
Rate: 100,
Burst: 10,
SkipFunc: func(r *http.Request) bool {
// Don't rate limit health checks or metrics
return r.URL.Path == "/health" || r.URL.Path == "/metrics"
},
}))The middleware sets these headers:
X-RateLimit-Limit: Maximum requests per secondX-RateLimit-Remaining: Remaining requests in current windowRetry-After: Seconds to wait before retrying (when limit exceeded)The middleware automatically cleans up expired rate limit entries:
s.Use(middleware.RateLimitWithConfig(middleware.RateLimitConfig{
Rate: 100,
Burst: 10,
CleanupInterval: time.Minute, // How often to run cleanup
ExpirationTime: 5 * time.Minute, // When to expire entries
}))s := helix.New()
// Global rate limit: 100 req/s, burst of 10
s.Use(middleware.RateLimit(100, 10))
// Stricter rate limit for API routes
api := s.Group("/api", middleware.RateLimit(50, 5))
// Even stricter for admin routes
admin := api.Group("/admin", middleware.RateLimit(10, 2))Limits the number of requests per client using a token bucket algorithm.
// 100 requests per second, burst of 10
s.Use(middleware.RateLimit(100, 10))s.Use(middleware.RateLimitWithConfig(middleware.RateLimitConfig{
Rate: 100, // requests per second
Burst: 10, // maximum burst
KeyFunc: func(r *http.Request) string {
// Rate limit by API key instead of IP
return r.Header.Get("X-API-Key")
},
Handler: func(w http.ResponseWriter, r *http.Request) {
// Custom rate limit response
helix.TooManyRequests(w, "Rate limit exceeded")
},
SkipFunc: func(r *http.Request) bool {
// Skip rate limiting for health checks
return r.URL.Path == "/health"
},
CleanupInterval: time.Minute,
ExpirationTime: 5 * time.Minute,
}))X-RateLimit-Limit, X-RateLimit-Remaining, Retry-After)The token bucket algorithm allows:
Example: Rate=100, Burst=10 means:
Default behavior limits by client IP:
s.Use(middleware.RateLimit(100, 10))The middleware extracts the client IP from:
X-Forwarded-For header (first IP)X-Real-IP headerRemoteAddr from requestLimit by API key instead of IP:
s.Use(middleware.RateLimitWithConfig(middleware.RateLimitConfig{
Rate: 100,
Burst: 10,
KeyFunc: func(r *http.Request) string {
return r.Header.Get("X-API-Key")
},
}))Limit by authenticated user:
s.Use(middleware.RateLimitWithConfig(middleware.RateLimitConfig{
Rate: 100,
Burst: 10,
KeyFunc: func(r *http.Request) string {
// Extract user ID from context or header
userID := getUserID(r)
return userID
},
}))s.Use(middleware.RateLimitWithConfig(middleware.RateLimitConfig{
Rate: 100,
Burst: 10,
Handler: func(w http.ResponseWriter, r *http.Request) {
helix.WriteProblem(w, helix.ErrTooManyRequests.WithDetail(
"Rate limit exceeded. Please try again later.",
))
},
}))Skip rate limiting for specific requests:
s.Use(middleware.RateLimitWithConfig(middleware.RateLimitConfig{
Rate: 100,
Burst: 10,
SkipFunc: func(r *http.Request) bool {
// Don't rate limit health checks or metrics
return r.URL.Path == "/health" || r.URL.Path == "/metrics"
},
}))The middleware sets these headers:
X-RateLimit-Limit: Maximum requests per secondX-RateLimit-Remaining: Remaining requests in current windowRetry-After: Seconds to wait before retrying (when limit exceeded)The middleware automatically cleans up expired rate limit entries:
s.Use(middleware.RateLimitWithConfig(middleware.RateLimitConfig{
Rate: 100,
Burst: 10,
CleanupInterval: time.Minute, // How often to run cleanup
ExpirationTime: 5 * time.Minute, // When to expire entries
}))s := helix.New()
// Global rate limit: 100 req/s, burst of 10
s.Use(middleware.RateLimit(100, 10))
// Stricter rate limit for API routes
api := s.Group("/api", middleware.RateLimit(50, 5))
// Even stricter for admin routes
admin := api.Group("/admin", middleware.RateLimit(10, 2))// 100 requests per second, burst of 10
s.Use(middleware.RateLimit(100, 10))s.Use(middleware.RateLimitWithConfig(middleware.RateLimitConfig{
Rate: 100, // requests per second
Burst: 10, // maximum burst
KeyFunc: func(r *http.Request) string {
// Rate limit by API key instead of IP
return r.Header.Get("X-API-Key")
},
Handler: func(w http.ResponseWriter, r *http.Request) {
// Custom rate limit response
helix.TooManyRequests(w, "Rate limit exceeded")
},
SkipFunc: func(r *http.Request) bool {
// Skip rate limiting for health checks
return r.URL.Path == "/health"
},
CleanupInterval: time.Minute,
ExpirationTime: 5 * time.Minute,
}))s.Use(middleware.RateLimit(100, 10))s.Use(middleware.RateLimitWithConfig(middleware.RateLimitConfig{
Rate: 100,
Burst: 10,
KeyFunc: func(r *http.Request) string {
return r.Header.Get("X-API-Key")
},
}))s.Use(middleware.RateLimitWithConfig(middleware.RateLimitConfig{
Rate: 100,
Burst: 10,
KeyFunc: func(r *http.Request) string {
// Extract user ID from context or header
userID := getUserID(r)
return userID
},
}))s.Use(middleware.RateLimitWithConfig(middleware.RateLimitConfig{
Rate: 100,
Burst: 10,
Handler: func(w http.ResponseWriter, r *http.Request) {
helix.WriteProblem(w, helix.ErrTooManyRequests.WithDetail(
"Rate limit exceeded. Please try again later.",
))
},
}))s.Use(middleware.RateLimitWithConfig(middleware.RateLimitConfig{
Rate: 100,
Burst: 10,
SkipFunc: func(r *http.Request) bool {
// Don't rate limit health checks or metrics
return r.URL.Path == "/health" || r.URL.Path == "/metrics"
},
}))s.Use(middleware.RateLimitWithConfig(middleware.RateLimitConfig{
Rate: 100,
Burst: 10,
CleanupInterval: time.Minute, // How often to run cleanup
ExpirationTime: 5 * time.Minute, // When to expire entries
}))s := helix.New()
// Global rate limit: 100 req/s, burst of 10
s.Use(middleware.RateLimit(100, 10))
// Stricter rate limit for API routes
api := s.Group("/api", middleware.RateLimit(50, 5))
// Even stricter for admin routes
admin := api.Group("/admin", middleware.RateLimit(10, 2))// 100 requests per second, burst of 10
s.Use(middleware.RateLimit(100, 10))s.Use(middleware.RateLimitWithConfig(middleware.RateLimitConfig{
Rate: 100, // requests per second
Burst: 10, // maximum burst
KeyFunc: func(r *http.Request) string {
// Rate limit by API key instead of IP
return r.Header.Get("X-API-Key")
},
Handler: func(w http.ResponseWriter, r *http.Request) {
// Custom rate limit response
helix.TooManyRequests(w, "Rate limit exceeded")
},
SkipFunc: func(r *http.Request) bool {
// Skip rate limiting for health checks
return r.URL.Path == "/health"
},
CleanupInterval: time.Minute,
ExpirationTime: 5 * time.Minute,
}))s.Use(middleware.RateLimit(100, 10))s.Use(middleware.RateLimitWithConfig(middleware.RateLimitConfig{
Rate: 100,
Burst: 10,
KeyFunc: func(r *http.Request) string {
return r.Header.Get("X-API-Key")
},
}))s.Use(middleware.RateLimitWithConfig(middleware.RateLimitConfig{
Rate: 100,
Burst: 10,
KeyFunc: func(r *http.Request) string {
// Extract user ID from context or header
userID := getUserID(r)
return userID
},
}))s.Use(middleware.RateLimitWithConfig(middleware.RateLimitConfig{
Rate: 100,
Burst: 10,
Handler: func(w http.ResponseWriter, r *http.Request) {
helix.WriteProblem(w, helix.ErrTooManyRequests.WithDetail(
"Rate limit exceeded. Please try again later.",
))
},
}))s.Use(middleware.RateLimitWithConfig(middleware.RateLimitConfig{
Rate: 100,
Burst: 10,
SkipFunc: func(r *http.Request) bool {
// Don't rate limit health checks or metrics
return r.URL.Path == "/health" || r.URL.Path == "/metrics"
},
}))s.Use(middleware.RateLimitWithConfig(middleware.RateLimitConfig{
Rate: 100,
Burst: 10,
CleanupInterval: time.Minute, // How often to run cleanup
ExpirationTime: 5 * time.Minute, // When to expire entries
}))s := helix.New()
// Global rate limit: 100 req/s, burst of 10
s.Use(middleware.RateLimit(100, 10))
// Stricter rate limit for API routes
api := s.Group("/api", middleware.RateLimit(50, 5))
// Even stricter for admin routes
admin := api.Group("/admin", middleware.RateLimit(10, 2))