Documentation
¶
Overview ¶
Package core implements the HTTP machinery shared by every resource package. Decomposed into one concern per file: URL building, header building, send, retry policy, response parsing, and telemetry. Internal package — users cannot import it.
Index ¶
- Constants
- func BuildHeaders(in HeadersInput) http.Header
- func BuildURL(baseURL, apiPath, path string, query map[string]string) string
- func ComputeBackoff(attempt int, retryAfter time.Duration, policy RetryPolicy) time.Duration
- func IsIdempotent(method string, hasIdempotencyKey bool) bool
- func IsRetryableStatus(status int) bool
- func ParseErrorBody(bodyText string) (code, message string, details map[string]any)
- func ParseRetryAfter(header string) time.Duration
- func ParseSuccessBody(r *Response, out any) error
- type Client
- type ClientOptions
- type HeadersInput
- type Request
- type Response
- type RetryPolicy
- type SendInput
- type Telemetry
Constants ¶
const EnvVarAPIKey = "THREECOMMON_API_KEY"
EnvVarAPIKey is the environment variable consulted when threecommon.Config.APIKey is empty.
Variables ¶
This section is empty.
Functions ¶
func BuildHeaders ¶
func BuildHeaders(in HeadersInput) http.Header
BuildHeaders returns a fresh http.Header populated with every header the SDK sends on every request.
func BuildURL ¶
BuildURL concatenates baseURL + apiPath + path and appends a query string. Pure function; no I/O. Trailing slashes on baseURL are trimmed; missing leading slashes on path are added.
Query values are stable-sorted by key for deterministic output.
func ComputeBackoff ¶
ComputeBackoff returns the next sleep duration. When retryAfter is non-zero (e.g. parsed from a Retry-After header) it takes precedence, capped at policy.Max. Otherwise: exponential 2^attempt * Initial, capped at Max, with optional full-jitter randomization.
func IsIdempotent ¶
IsIdempotent reports whether the SDK may safely retry a request with the given method. Caller-supplied idempotency keys upgrade non-idempotent methods.
func IsRetryableStatus ¶
IsRetryableStatus reports whether status is one we should retry on alongside method idempotency.
func ParseErrorBody ¶
ParseErrorBody returns the parsed code, message, and details from the standard {"error": {...}} response shape. Returns zero values when the body can't be parsed.
func ParseRetryAfter ¶
ParseRetryAfter parses a Retry-After header value. Accepts either delta-seconds or an HTTP-date. Returns 0 for missing, malformed, or already-elapsed values.
func ParseSuccessBody ¶
ParseSuccessBody decodes a 2xx body into out. Empty or non-JSON bodies are silently ignored — out keeps its zero value. Returns a JSON error only when the body looks like JSON but is malformed.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client orchestrates URL building → header building → send → parse → error mapping → retry. One instance per github.com/3-Common/sdk/sdk-go/client.API.
func NewClient ¶
func NewClient(opts ClientOptions) *Client
NewClient constructs a *Client. Defaults Sleep and Now when omitted.
func NewFromConfig ¶
func NewFromConfig(cfg threecommon.Config) (*Client, error)
NewFromConfig validates a threecommon.Config, fills in defaults, and returns a ready-to-use *Client. Resource packages and the [client] aggregator both call this so the entire SDK shares one validation path.
type ClientOptions ¶
type ClientOptions struct {
APIKey string
BaseURL string
APIVersion string
SDKVersion string
Timeout time.Duration
Retry RetryPolicy
HTTPClient *http.Client
Telemetry *Telemetry
Logger threecommon.Logger
NowFunc func() time.Time // injectable for tests
SleepFunc func(ctx context.Context, d time.Duration) error // injectable for tests
}
ClientOptions configures a *Client.
type HeadersInput ¶
type HeadersInput struct {
APIKey string
APIVersion string
SDKVersion string
UserAgentSuffix string
TelemetryHeader string // "" omits the header
IdempotencyKey string // "" omits the header
HasBody bool // false omits Content-Type (bodyless requests)
}
HeadersInput captures everything BuildHeaders needs to populate a request's header map. Pre-resolved by the caller so this stays a pure function.
type Request ¶
type Request struct {
Method string
Path string
Query map[string]string
Body any
Out any // pointer to decode 2xx body into
IdempotencyKey string // optional
Timeout time.Duration // overrides ClientOptions.Timeout when non-zero
MaxRetries int // overrides ClientOptions.Retry.MaxRetries when non-zero (use -1 for "no retries")
}
Request describes one logical SDK call. The httpclient handles URL building, retries, and error mapping; the caller supplies path, method, query, and body.
type Response ¶
Response is a fully-buffered, post-read normalization of *http.Response. Headers are kept as the canonical http.Header map; the body is read once into a string and never read again from the underlying response. Callers must not pass the wrapped *http.Response back to the network.
func ReadResponse ¶
ReadResponse drains response body and returns a Response. The original *http.Response body is closed before this returns.
type RetryPolicy ¶
RetryPolicy mirrors threecommon.RetryDelay plus a max-attempts cap.
type SendInput ¶
type SendInput struct {
HTTPClient *http.Client
URL string
Method string
Headers http.Header
Body any // marshaled to JSON when non-nil
Timeout time.Duration // 0 disables the per-request timeout
}
SendInput captures everything Send needs. Pre-built so Send stays a thin wrapper around the standard library — no header building, no URL building, no retry logic.
type Telemetry ¶
type Telemetry struct {
// contains filtered or unexported fields
}
Telemetry tracks one previous-request snapshot per client and emits the Threecommon-Client-Telemetry header value for the next request. Goroutine- safe — the snapshot is updated under a mutex because every field is read together.
func NewTelemetry ¶
NewTelemetry returns a *Telemetry in the given enabled state.
func TelemetryFromClient ¶
TelemetryFromClient returns the *Telemetry behind a *Client so the aggregator package can implement github.com/3-Common/sdk/sdk-go/client.API.DisableTelemetry.
func (*Telemetry) Disable ¶
func (t *Telemetry) Disable()
Disable turns telemetry off and clears the cached snapshot.
func (*Telemetry) Enabled ¶
Enabled reports whether the next Telemetry.HeaderValue call will emit a header.
func (*Telemetry) HeaderValue ¶
HeaderValue returns the JSON value for the Threecommon-Client-Telemetry header on the next request. The empty string means "do not send the header".