httpclient

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: 11 Imported by: 0

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

View Source
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

func DoJSON(c *http.Client, req *http.Request, out any) error

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

func New(cfg Config) (*http.Client, error)

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

type StatusError struct {
	StatusCode int
	Status     string
	Body       []byte
}

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

Jump to

Keyboard shortcuts

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