Documentation
¶
Index ¶
- Variables
- func APIKeyAuth(apiKeyStore store.APIKeyStore, next http.Handler) http.Handler
- func CircuitBreakerMiddleware(cb *CircuitBreaker, fallbackHandler http.Handler) func(http.Handler) http.Handler
- func InputValidation(cfg ValidationConfig, next http.Handler) http.Handler
- type CircuitBreaker
- func (cb *CircuitBreaker) Counts() (failures, successes int)
- func (cb *CircuitBreaker) Execute(ctx context.Context, fn func(ctx context.Context) error) error
- func (cb *CircuitBreaker) OnStateChange(fn func(from, to CircuitState))
- func (cb *CircuitBreaker) RecordFailure()
- func (cb *CircuitBreaker) RecordSuccess()
- func (cb *CircuitBreaker) Reset()
- func (cb *CircuitBreaker) State() CircuitState
- type CircuitBreakerConfig
- type CircuitBreakerRegistry
- func (r *CircuitBreakerRegistry) All() map[string]*CircuitBreaker
- func (r *CircuitBreakerRegistry) Get(name string) *CircuitBreaker
- func (r *CircuitBreakerRegistry) GetOrCreate(config CircuitBreakerConfig) *CircuitBreaker
- func (r *CircuitBreakerRegistry) Register(cb *CircuitBreaker)
- func (r *CircuitBreakerRegistry) Remove(name string)
- func (r *CircuitBreakerRegistry) ResetAll()
- type CircuitState
- type TenantContext
- type ValidationConfig
Constants ¶
This section is empty.
Variables ¶
var APIKeyContextKey = apiKeyContextKey{}
APIKeyContextKey is the context key for the authenticated API key.
var ErrCircuitOpen = errors.New("circuit breaker is open")
ErrCircuitOpen is returned when the circuit breaker is in the open state and refuses to execute the request.
var TenantContextKey = tenantContextKey{}
TenantContextKey is the context key for the tenant context.
Functions ¶
func APIKeyAuth ¶
APIKeyAuth returns HTTP middleware that authenticates requests using the X-API-Key header.
If the header is present, the middleware validates the key against the provided store. On success it sets TenantContext and the APIKey in the request context and calls next. On failure (invalid, expired, inactive key) it returns 401 Unauthorized.
If the header is absent, the middleware calls next without modification, allowing downstream handlers or other auth middleware (e.g., JWT) to handle authentication.
func CircuitBreakerMiddleware ¶
func CircuitBreakerMiddleware(cb *CircuitBreaker, fallbackHandler http.Handler) func(http.Handler) http.Handler
CircuitBreakerMiddleware returns an HTTP middleware that wraps the next handler with circuit breaker protection. When the circuit is open, the fallbackHandler is invoked instead (typically returning 503 Service Unavailable with a Retry-After header).
Usage:
cb := middleware.NewCircuitBreaker(config)
mux.Handle("/api/downstream",
middleware.CircuitBreakerMiddleware(cb, fallback)(handler))
func InputValidation ¶
func InputValidation(cfg ValidationConfig, next http.Handler) http.Handler
InputValidation returns an http.Handler middleware that validates request body size, content-type, and JSON well-formedness.
Types ¶
type CircuitBreaker ¶
type CircuitBreaker struct {
// contains filtered or unexported fields
}
CircuitBreaker implements the circuit breaker pattern for protecting calls to downstream services.
func NewCircuitBreaker ¶
func NewCircuitBreaker(config CircuitBreakerConfig) *CircuitBreaker
NewCircuitBreaker creates a new circuit breaker with the given configuration.
func (*CircuitBreaker) Counts ¶
func (cb *CircuitBreaker) Counts() (failures, successes int)
Counts returns the current failure and success counters (useful for diagnostics and testing).
func (*CircuitBreaker) Execute ¶
Execute runs fn through the circuit breaker. If the circuit is open, it returns ErrCircuitOpen without invoking fn. In the half-open state it limits concurrency to MaxConcurrent. Success and failure are recorded automatically based on the error returned by fn.
func (*CircuitBreaker) OnStateChange ¶
func (cb *CircuitBreaker) OnStateChange(fn func(from, to CircuitState))
OnStateChange registers a callback invoked whenever the circuit transitions between states. The callback is called while the breaker's lock is held, so it must not call back into the breaker.
func (*CircuitBreaker) RecordFailure ¶
func (cb *CircuitBreaker) RecordFailure()
RecordFailure records a failed operation.
func (*CircuitBreaker) RecordSuccess ¶
func (cb *CircuitBreaker) RecordSuccess()
RecordSuccess records a successful operation.
func (*CircuitBreaker) Reset ¶
func (cb *CircuitBreaker) Reset()
Reset manually resets the circuit breaker to the closed state, clearing all counters.
func (*CircuitBreaker) State ¶
func (cb *CircuitBreaker) State() CircuitState
State returns the current state of the circuit breaker. If the circuit is open and the timeout has elapsed, this will report HalfOpen (but does not transition -- that occurs on the next Execute call).
type CircuitBreakerConfig ¶
type CircuitBreakerConfig struct {
// Name identifies this circuit breaker instance.
Name string `json:"name"`
// FailureThreshold is the number of consecutive failures required to
// trip the circuit from closed to open. Defaults to 5.
FailureThreshold int `json:"failure_threshold"`
// SuccessThreshold is the number of consecutive successes in the
// half-open state required to close the circuit. Defaults to 2.
SuccessThreshold int `json:"success_threshold"`
// Timeout is the duration the circuit stays open before transitioning
// to half-open to test recovery. Defaults to 30 seconds.
Timeout time.Duration `json:"timeout"`
// MaxConcurrent is the maximum number of concurrent probe requests
// allowed in the half-open state. Defaults to 1.
MaxConcurrent int `json:"max_concurrent"`
}
CircuitBreakerConfig holds the parameters for a circuit breaker.
type CircuitBreakerRegistry ¶
type CircuitBreakerRegistry struct {
// contains filtered or unexported fields
}
CircuitBreakerRegistry manages a collection of named circuit breakers.
func NewCircuitBreakerRegistry ¶
func NewCircuitBreakerRegistry() *CircuitBreakerRegistry
NewCircuitBreakerRegistry creates a new empty registry.
func (*CircuitBreakerRegistry) All ¶
func (r *CircuitBreakerRegistry) All() map[string]*CircuitBreaker
All returns a snapshot of all circuit breakers currently in the registry.
func (*CircuitBreakerRegistry) Get ¶
func (r *CircuitBreakerRegistry) Get(name string) *CircuitBreaker
Get returns the circuit breaker with the given name, or nil if not found.
func (*CircuitBreakerRegistry) GetOrCreate ¶
func (r *CircuitBreakerRegistry) GetOrCreate(config CircuitBreakerConfig) *CircuitBreaker
GetOrCreate returns the circuit breaker for name if it exists, otherwise creates one with the provided config, registers it, and returns it.
func (*CircuitBreakerRegistry) Register ¶
func (r *CircuitBreakerRegistry) Register(cb *CircuitBreaker)
Register adds a circuit breaker to the registry under its config name. If a breaker with the same name already exists it is replaced.
func (*CircuitBreakerRegistry) Remove ¶
func (r *CircuitBreakerRegistry) Remove(name string)
Remove deletes the named circuit breaker from the registry.
func (*CircuitBreakerRegistry) ResetAll ¶
func (r *CircuitBreakerRegistry) ResetAll()
ResetAll resets every circuit breaker in the registry to the closed state.
type CircuitState ¶
type CircuitState int
CircuitState represents the current state of a circuit breaker.
const ( // CircuitClosed is the normal operating state. Requests pass through. CircuitClosed CircuitState = iota // CircuitOpen indicates the circuit has tripped. Requests are rejected. CircuitOpen // CircuitHalfOpen indicates the circuit is testing whether the downstream // service has recovered. CircuitHalfOpen )
func (CircuitState) String ¶
func (s CircuitState) String() string
String returns a human-readable representation of the circuit state.
type TenantContext ¶
type TenantContext struct {
CompanyID uuid.UUID
OrgID *uuid.UUID
ProjectID *uuid.UUID
Permissions []string
APIKeyID uuid.UUID
}
TenantContext holds the tenant scoping information extracted from an API key.
func TenantFromContext ¶
func TenantFromContext(ctx context.Context) (*TenantContext, bool)
TenantFromContext extracts the TenantContext from the request context, if present.
type ValidationConfig ¶
type ValidationConfig struct {
// MaxBodySize is the maximum allowed request body size in bytes.
// Defaults to 1MB if zero.
MaxBodySize int64
// AllowedContentTypes lists the Content-Type values accepted for requests
// with a body (POST, PUT, PATCH). If empty, defaults to ["application/json"].
AllowedContentTypes []string
// ValidateJSON when true requires that request bodies with content-type
// application/json are well-formed JSON.
ValidateJSON bool
}
ValidationConfig holds settings for the input validation middleware.
func DefaultValidationConfig ¶
func DefaultValidationConfig() ValidationConfig
DefaultValidationConfig returns a config with sensible defaults.