httpmw

package
v0.8.1 Latest Latest
Warning

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

Go to latest
Published: Jul 20, 2026 License: MIT Imports: 8 Imported by: 0

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.

func (*RetryTransport) RoundTrip

func (t *RetryTransport) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip executes the request, retrying on configured statuses until the attempt budget is exhausted or the context is canceled. The request body is rewound between attempts.

Jump to

Keyboard shortcuts

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