Documentation
¶
Overview ¶
Package httpclient builds configured *http.Client values for calling upstream services, and helps consume their JSON responses. It is the transport half of a typed service client (see `skit add http-client`): the generated client package builds one of these in its constructor, then its methods assemble requests and decode responses through DoJSON.
The transport is composed from httpmw middlewares — retry (5xx/429 + Retry-After), a User-Agent, an idempotency key, arbitrary headers — and, when OAuth2 is configured, an OAuth2 client_credentials bearer. Composition order (httpmw.Chain) puts retry outermost and auth innermost, so a retried attempt re-attaches the current token.
Index ¶
Constants ¶
const DefaultTimeout = 30 * time.Second
DefaultTimeout is the per-request client timeout when Config.Timeout is unset.
Variables ¶
This section is empty.
Functions ¶
func DoJSON ¶
DoJSON sends req through c, and on a 2xx response decodes the JSON body into out (skip decoding by passing a nil out). A non-2xx response yields a *StatusError; a transport error is returned as-is. The response body is always closed. An empty 2xx body is not an error (out is left unchanged).
func New ¶
New builds an *http.Client with the composed transport. It returns an error only when OAuth2 is set but invalid.
func OAuth2Transport ¶
func OAuth2Transport(cfg OAuth2Config, base http.RoundTripper) (http.RoundTripper, error)
OAuth2Transport returns an http.RoundTripper that adds an OAuth2 client_credentials bearer token to every request, refreshing and caching it automatically, then delegates to base (or http.DefaultTransport when nil).
base is the transport for business requests — pass the wire transport here and compose retries/headers ABOVE this in the chain (httpmw.Chain), so a retried request re-attaches the current token. Token fetches go through their own small client (TokenTimeout), never through base, so they are not themselves retried or wrapped.
Types ¶
type Config ¶
type Config struct {
// Timeout is the per-request client timeout (default DefaultTimeout). It
// bounds the whole call including retries.
Timeout time.Duration
// Retry, when non-nil, wraps the transport in retry (5xx/429 + Retry-After).
Retry *httpmw.RetryConfig
// OAuth2, when non-nil, adds a client_credentials bearer token.
OAuth2 *OAuth2Config
// UserAgent, when non-empty, sets the User-Agent header (product name).
UserAgent string
// Version, Environment refine the User-Agent to "product/version (env)".
Version string
Environment string
// IdempotencyHeader, when non-empty, injects a per-request idempotency key
// under this header (retry-safe: kept stable across retries).
IdempotencyHeader string
// Headers are static headers set on every request.
Headers map[string]string
// Base is the innermost (wire) transport (default http.DefaultTransport).
Base http.RoundTripper
}
Config assembles an upstream HTTP client. All fields are optional except that OAuth2, when set, requires its own required fields. The zero Config yields a plain client with DefaultTimeout and no retry/auth.
type OAuth2Config ¶
type OAuth2Config struct {
// TokenURL is the full OAuth2 token endpoint.
TokenURL string
// ClientID, ClientSecret are the client_credentials grant.
ClientID string
ClientSecret string
// Scopes are requested with the token; may be empty.
Scopes []string
// TokenTimeout bounds each token fetch (default 10s). The token fetch uses
// its own client, separate from the business request transport.
TokenTimeout time.Duration
}
OAuth2Config configures an OAuth2 client_credentials token source. TokenURL, ClientID and ClientSecret are required. Scopes are baked into the token source (a client needs one instance per scope set — the token cache is per source).
type StatusError ¶
StatusError is returned by DoJSON when the upstream responds with a non-2xx status. It carries the status and a (capped) snapshot of the body so callers can branch on StatusCode with errors.As and surface the upstream message.
func (*StatusError) Error ¶
func (e *StatusError) Error() string