ratelimit

package
v4.0.0 Latest Latest
Warning

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

Go to latest
Published: Jul 11, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

Documentation

Overview

Package ratelimit provides stable rate-limit middleware over Limiter.

The middleware owns HTTP behavior while storage and quota decisions stay behind the Limiter contract. Limiter is a v3 migration shim alias for Limiter; prefer the package-local name in new application code before v4 shrinks broad root ports. Use contrib adapters for concrete stores, and keep dangerous local bypass configuration restricted to trusted proxies.

Purpose: See the package summary above. Import: `github.com/aatuh/api-toolkit/v4/middleware/ratelimit`. Example: See docs/api-reference.md for package example links and docs/cookbook.md for task recipes. Errors: Constructors, parsers, and handlers return or write documented errors according to their signatures; packages with plain data types do not add hidden error channels. Concurrency: Treat configured middleware and helpers as immutable after construction; request and response values remain request-scoped unless a type documents stronger guarantees. Stability: Stable core API under VERSIONING.md and scripts/apicheck.sh. When not to use: Prefer net/http, application-owned types, or narrower helpers when this package contract is not needed.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func SetRateLimitHeaders

func SetRateLimitHeaders(w http.ResponseWriter, quota Quota, config HeaderConfig)

SetRateLimitHeaders writes standard quota headers when config is enabled.

Example
package main

import (
	"fmt"
	"net/http/httptest"

	"github.com/aatuh/api-toolkit/v4/middleware/ratelimit"
)

func main() {
	recorder := httptest.NewRecorder()
	ratelimit.SetRateLimitHeaders(recorder, ratelimit.Quota{
		Limit:     10,
		Remaining: 9,
	}, ratelimit.DefaultHeaderConfig())

	fmt.Println(recorder.Header().Get("RateLimit-Limit"))
	fmt.Println(recorder.Header().Get("RateLimit-Remaining"))

}
Output:
10
9

func WriteRateLimited

func WriteRateLimited(w http.ResponseWriter, decision Decision, config HeaderConfig)

WriteRateLimited writes a 429 Problem Details response with quota headers.

Types

type Decision

type Decision struct {
	Allowed    bool
	Quota      Quota
	RetryAfter time.Duration
}

Decision describes an allow/deny decision with optional quota metadata.

type HeaderConfig

type HeaderConfig struct {
	Enabled          bool
	LimitHeader      string
	RemainingHeader  string
	ResetHeader      string
	RetryAfterHeader string
}

HeaderConfig configures standard rate-limit response headers.

func DefaultHeaderConfig

func DefaultHeaderConfig() HeaderConfig

DefaultHeaderConfig returns enabled RFC-compatible quota header names.

type KeyFn

type KeyFn func(*http.Request) string

KeyFn extracts a key for rate limiting buckets.

type Limiter

type Limiter interface {
	Allow(ctx context.Context, key string) (allowed bool, retryAfter time.Duration, err error)
}

Limiter is the package-local rate limiter contract for middleware users.

Example
package main

import (
	"context"
	"time"

	"github.com/aatuh/api-toolkit/v4/middleware/ratelimit"
)

type exampleLimiter struct{}

func (exampleLimiter) Allow(context.Context, string) (bool, time.Duration, error) {
	return true, 0, nil
}

func main() {
	var limiter ratelimit.Limiter = exampleLimiter{}
	_ = limiter
}

type Middleware

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

Middleware enforces in-memory token bucket rate limits.

func New

func New(opts Options) (*Middleware, error)

New constructs a rate limiting middleware with defaults.

func (*Middleware) Handler

func (m *Middleware) Handler(next http.Handler) http.Handler

Handler wraps the next handler with rate limiting logic.

func (*Middleware) Middleware

func (m *Middleware) Middleware() func(http.Handler) http.Handler

Middleware implements ports.Middleware via Handler adapter.

type Options

type Options struct {
	Capacity   float64 // tokens
	RefillRate float64 // tokens per second
	Key        KeyFn   // how to key buckets
	RetryAfter time.Duration
	Clock      ports.Clock
	// Limiter overrides the default in-memory limiter with a shared limiter.
	Limiter Limiter
	// ClientIPResolver derives client identity from trusted proxies.
	ClientIPResolver identity.Resolver
	// StateTTL evicts buckets that have been idle for this duration.
	StateTTL time.Duration
	// CleanupInterval controls how often eviction runs.
	CleanupInterval time.Duration

	// SkipEnabled toggles honoring the SkipHeader. Useful for tests/dev.
	SkipEnabled bool
	// SkipHeader contains the header name that, when present, bypasses limiting.
	// When empty, no bypass is applied.
	SkipHeader string
	// AllowDangerousDevBypasses enables skip headers only when request comes from trusted proxies.
	AllowDangerousDevBypasses bool
	// FailOpen controls whether requests pass through when limiter errors.
	FailOpen bool
	// OnError receives limiter errors, when present.
	OnError func(error)
	// HeaderConfig enables standard RateLimit-* response headers when configured.
	HeaderConfig HeaderConfig
}

Options configures the rate limit middleware.

type Quota

type Quota struct {
	Limit      int
	Remaining  int
	Reset      time.Time
	RetryAfter time.Duration
}

Quota describes a rate-limit quota snapshot for response headers.

func QuotaFromDecision

func QuotaFromDecision(decision Decision) Quota

QuotaFromDecision extracts quota metadata from a decision.

Jump to

Keyboard shortcuts

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