Compose client middleware¶
httpclient provides the hardened *http.Client; the per-request behaviour — retry,
circuit breaking, credentials, logging — comes from
go/transit's client round-trippers. This guide
shows how the two fit together and in what order.
import (
"gitlab.com/phpboyscout/go/httpclient"
transithttp "gitlab.com/phpboyscout/go/transit/http"
)
The two wiring options¶
NewClient takes two middleware-related options:
| Option | Wraps | Use for |
|---|---|---|
WithRetry(cfg) |
the transport directly, closest to the wire | automatic retry of transient failures |
WithClientMiddleware(chain) |
the transport outside retry | everything else: circuit breaker, auth, logging, rate limit |
Both take go/transit types. Retry is applied closest to the raw transport; the
ClientChain wraps the result, so a chain member (a circuit breaker, a logger) sees one
logical call rather than each retry attempt.
A full client stack¶
client := httpclient.NewClient(
httpclient.WithTimeout(10*time.Second),
// retry sits closest to the transport
httpclient.WithRetry(transithttp.DefaultRetryConfig()),
// the chain wraps retry — breaker outermost so it sees the post-retry verdict
httpclient.WithClientMiddleware(transithttp.NewClientChain(
transithttp.WithCircuitBreaker(log, transithttp.DefaultCircuitBreakerConfig()),
transithttp.WithBearerToken(token),
transithttp.WithRequestLogging(log),
)),
)
This produces the layering breaker → auth → logging → retry → transport. The
transit middleware model
explains why the breaker belongs outside retry.
Available chain middleware¶
From go/transit/http, for use inside NewClientChain:
WithCircuitBreaker(log, cfg)— fail fast while a downstream is unhealthy.WithBearerToken(token)/WithBasicAuth(user, pass)— credentials, pinned to the first host so a redirect cannot capture them.WithRateLimit(rps)— throttle outbound requests.WithRequestLogging(log)— debug-log each request.
Bring your own transport¶
WithTransport(rt) replaces the hardened transport entirely (retry and the chain still
wrap it). WithTLSConfig/WithCertPool adjust TLS while keeping the hardened defaults.
See hardened defaults.