Documentation
¶
Overview ¶
Package httpmw provides outbound HTTP-client middleware: composable http.RoundTripper wrappers for resilient calls to upstream services.
RetryTransport retries throttled/unavailable responses (429 and 503 by default) using the shared retry.Backoff policy, honoring a server-supplied Retry-After header (RFC 7231 §7.1.3) when present. It rewinds the request body between attempts (buffering in memory when the body is not otherwise replayable) and aborts as soon as the request context is canceled. Wrap it around any http.RoundTripper (or http.DefaultTransport when nil) and install it on an http.Client.
Usage ¶
client := &http.Client{
Transport: httpmw.NewRetryTransport(nil, httpmw.RetryConfig{
Backoff: retry.Backoff{
Base: 200 * time.Millisecond, Max: 5 * time.Second,
MaxAttempts: 4, Jitter: 0.2,
},
}),
}
resp, err := client.Get("https://upstream/api")
Config ¶
RetryConfig fields:
- Backoff (retry.Backoff): inter-attempt delay and the total-attempt budget via MaxAttempts. MaxAttempts <= 1 disables retries (a single try).
- Statuses ([]int): status codes that trigger a retry. Empty defaults to {429 Too Many Requests, 503 Service Unavailable}.
- DisableRetryAfter (bool): when false (default), a retryable response's Retry-After value (delta-seconds or HTTP-date) is preferred over the backoff delay, clamped to Backoff.Max when Max > 0.
- Rand (func() float64): source of backoff jitter in [0,1); defaults to math/rand/v2. Override for deterministic tests.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Chain ¶ added in v0.6.0
func Chain(base http.RoundTripper, mws ...Middleware) http.RoundTripper
Chain wraps base (or http.DefaultTransport when nil) with mws, applied so that the FIRST middleware is outermost — it sees the request first and the response last. So Chain(base, Retry, UserAgent) runs Retry around UserAgent around base: a retried attempt re-applies UserAgent (and any auth) each time. Install the result as an http.Client's Transport.
Types ¶
type Middleware ¶ added in v0.6.0
type Middleware func(next http.RoundTripper) http.RoundTripper
Middleware wraps an http.RoundTripper, returning one that adds behavior around next. It is the composition unit for outbound HTTP: retries, header injection, auth, logging. Compose several with Chain.
func IdempotencyKey ¶ added in v0.6.0
func IdempotencyKey(header string) Middleware
IdempotencyKey returns a Middleware that sets header to a fresh UUID v4 only when the caller has not already set it. Leaving an existing value intact is what makes it retry-safe: a retried request carries the same key, so the server dedupes repeated attempts of one logical call. A blank header defaults to "Idempotency-Key".
func Retry ¶ added in v0.6.0
func Retry(cfg RetryConfig) Middleware
Retry is the RetryTransport as a Middleware, so it composes in a Chain. It is equivalent to NewRetryTransport(next, cfg) for the wrapped transport.
func SetHeader ¶ added in v0.6.0
func SetHeader(key, value string) Middleware
SetHeader returns a Middleware that sets key: value on every outbound request, overwriting any existing value. A blank key is a no-op.
func UserAgent ¶ added in v0.6.0
func UserAgent(product, version, env string) Middleware
UserAgent returns a Middleware that sets the User-Agent header to "product/version (env)", skipping any empty parts. A blank product is a no-op (User-Agent left untouched).
type RetryConfig ¶
type RetryConfig struct {
// Backoff drives the delay between attempts and the total-attempt budget via
// its MaxAttempts field. MaxAttempts <= 1 disables retries (a single try).
Backoff retry.Backoff
// Statuses are the response status codes that trigger a retry. When empty it
// defaults to {429 Too Many Requests, 503 Service Unavailable}.
Statuses []int
// DisableRetryAfter turns off honoring the server's Retry-After header. By
// default (false) a Retry-After value (delta-seconds or HTTP-date) on a
// retryable response is used in preference to the backoff delay, clamped to
// Backoff.Max when Max > 0.
DisableRetryAfter bool
// Rand returns a pseudo-random value in [0,1) used for backoff jitter. It
// defaults to math/rand/v2; override it in tests for determinism.
Rand func() float64
}
RetryConfig configures a RetryTransport.
type RetryTransport ¶
type RetryTransport struct {
// contains filtered or unexported fields
}
RetryTransport is an http.RoundTripper that retries retryable responses according to its RetryConfig. The zero value is not usable; build it with NewRetryTransport.
func NewRetryTransport ¶
func NewRetryTransport(next http.RoundTripper, cfg RetryConfig) *RetryTransport
NewRetryTransport wraps next (or http.DefaultTransport when nil) with retry behavior. The result is safe for concurrent use if next is.