httpx

package
v1.0.2 Latest Latest
Warning

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

Go to latest
Published: Dec 18, 2025 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Overview

Package httpx provides HTTP transport utilities for the Spooled SDK.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsAuthenticationError

func IsAuthenticationError(err error) bool

IsAuthenticationError returns true if the error is a 401 error.

func IsNotFoundError

func IsNotFoundError(err error) bool

IsNotFoundError returns true if the error is a 404 error.

func IsRateLimitError

func IsRateLimitError(err error) bool

IsRateLimitError returns true if the error is a 429 error.

func IsRetryable

func IsRetryable(err error) bool

IsRetryable returns true if the error is retryable.

func IsValidationError

func IsValidationError(err error) bool

IsValidationError returns true if the error is a 400/422 error.

func JSON

func JSON[T any](resp *Response) (*T, error)

JSON decodes a response body into a target value.

func JSONArray

func JSONArray[T any](resp *Response) ([]T, error)

JSONArray decodes a response body into a slice.

func ParseErrorFromResponse

func ParseErrorFromResponse(statusCode int, body []byte, headers http.Header) error

ParseErrorFromResponse parses an error from an HTTP response.

Types

type APIError

type APIError struct {
	StatusCode int            `json:"status_code,omitempty"`
	Code       string         `json:"code,omitempty"`
	Message    string         `json:"message,omitempty"`
	Details    map[string]any `json:"details,omitempty"`
	RequestID  string         `json:"request_id,omitempty"`
	RawBody    []byte         `json:"-"`
	Err        error          `json:"-"`
}

APIError is the base error type for all HTTP errors.

func AsAPIError

func AsAPIError(err error) (*APIError, bool)

AsAPIError extracts the underlying API error.

func (*APIError) Error

func (e *APIError) Error() string

Error implements the error interface.

func (*APIError) IsRetryable

func (e *APIError) IsRetryable() bool

IsRetryable returns true if the error is retryable.

func (*APIError) Unwrap

func (e *APIError) Unwrap() error

Unwrap returns the underlying error.

type AuthenticationError

type AuthenticationError struct{ *APIError }

AuthenticationError represents a 401 error.

func (*AuthenticationError) Unwrap

func (e *AuthenticationError) Unwrap() error

Unwrap returns the underlying API error.

type AuthorizationError

type AuthorizationError struct{ *APIError }

AuthorizationError represents a 403 error.

func (*AuthorizationError) Unwrap

func (e *AuthorizationError) Unwrap() error

Unwrap returns the underlying API error.

type CircuitBreaker

type CircuitBreaker struct {
	// contains filtered or unexported fields
}

CircuitBreaker implements the circuit breaker pattern.

func NewCircuitBreaker

func NewCircuitBreaker(cfg CircuitBreakerConfig) *CircuitBreaker

NewCircuitBreaker creates a new circuit breaker.

func (*CircuitBreaker) Allow

func (cb *CircuitBreaker) Allow() bool

Allow checks if a request is allowed through the circuit breaker.

func (*CircuitBreaker) Metrics

func (cb *CircuitBreaker) Metrics() CircuitBreakerMetrics

Metrics returns current circuit breaker metrics.

func (*CircuitBreaker) RecordFailure

func (cb *CircuitBreaker) RecordFailure()

RecordFailure records a failed request.

func (*CircuitBreaker) RecordSuccess

func (cb *CircuitBreaker) RecordSuccess()

RecordSuccess records a successful request.

func (*CircuitBreaker) Reset

func (cb *CircuitBreaker) Reset()

Reset resets the circuit breaker to its initial state.

func (*CircuitBreaker) State

func (cb *CircuitBreaker) State() CircuitState

State returns the current state of the circuit breaker.

type CircuitBreakerConfig

type CircuitBreakerConfig struct {
	Enabled          bool
	FailureThreshold int
	SuccessThreshold int
	Timeout          time.Duration
}

CircuitBreakerConfig configures the circuit breaker.

func DefaultCircuitBreakerConfig

func DefaultCircuitBreakerConfig() CircuitBreakerConfig

DefaultCircuitBreakerConfig returns the default circuit breaker configuration.

type CircuitBreakerMetrics

type CircuitBreakerMetrics struct {
	State           CircuitState
	FailureCount    int
	SuccessCount    int
	LastStateChange time.Time
}

CircuitBreakerMetrics holds circuit breaker metrics.

type CircuitBreakerOpenError

type CircuitBreakerOpenError struct{ *APIError }

CircuitBreakerOpenError represents a circuit breaker open error.

func NewCircuitBreakerOpenError

func NewCircuitBreakerOpenError() *CircuitBreakerOpenError

NewCircuitBreakerOpenError creates a new circuit breaker open error.

func (*CircuitBreakerOpenError) IsRetryable

func (e *CircuitBreakerOpenError) IsRetryable() bool

IsRetryable always returns false for circuit breaker errors.

func (*CircuitBreakerOpenError) Unwrap

func (e *CircuitBreakerOpenError) Unwrap() error

Unwrap returns the underlying API error.

type CircuitState

type CircuitState int

CircuitState represents the state of a circuit breaker.

const (
	// CircuitClosed - normal operation, requests are allowed
	CircuitClosed CircuitState = iota
	// CircuitOpen - circuit is open, requests are blocked
	CircuitOpen
	// CircuitHalfOpen - testing if circuit can be closed
	CircuitHalfOpen
)

func (CircuitState) String

func (s CircuitState) String() string

String returns the string representation of a circuit state.

type Config

type Config struct {
	BaseURL          string
	APIKey           string
	AccessToken      string
	RefreshToken     string
	AdminKey         string
	UserAgent        string
	Headers          map[string]string
	Timeout          time.Duration
	Retry            RetryConfig
	CircuitBreaker   CircuitBreakerConfig
	Logger           Logger
	AutoRefreshToken bool
}

Config holds configuration for the transport.

type ConflictError

type ConflictError struct{ *APIError }

ConflictError represents a 409 error.

func (*ConflictError) Unwrap

func (e *ConflictError) Unwrap() error

Unwrap returns the underlying API error.

type Logger

type Logger interface {
	Debug(msg string, keysAndValues ...any)
}

Logger is an interface for debug logging.

type NetworkError

type NetworkError struct{ *APIError }

NetworkError represents a network-level error.

func NewNetworkError

func NewNetworkError(err error) *NetworkError

NewNetworkError creates a new network error.

func (*NetworkError) IsRetryable

func (e *NetworkError) IsRetryable() bool

IsRetryable always returns true for network errors.

func (*NetworkError) Unwrap

func (e *NetworkError) Unwrap() error

Unwrap returns the underlying API error.

type NotFoundError

type NotFoundError struct{ *APIError }

NotFoundError represents a 404 error.

func (*NotFoundError) Unwrap

func (e *NotFoundError) Unwrap() error

Unwrap returns the underlying API error.

type PayloadTooLargeError

type PayloadTooLargeError struct{ *APIError }

PayloadTooLargeError represents a 413 error.

func (*PayloadTooLargeError) Unwrap

func (e *PayloadTooLargeError) Unwrap() error

Unwrap returns the underlying API error.

type RateLimitError

type RateLimitError struct {
	*APIError
	RetryAfter time.Duration
	Limit      int
	Remaining  int
	Reset      time.Time
}

RateLimitError represents a 429 error.

func (*RateLimitError) GetRetryAfter

func (e *RateLimitError) GetRetryAfter() int

GetRetryAfter returns the retry-after duration in seconds.

func (*RateLimitError) Unwrap

func (e *RateLimitError) Unwrap() error

Unwrap returns the underlying API error.

type Request

type Request struct {
	Method string
	Path   string
	Body   any
	// RawBody, when set, is sent verbatim as the request body (skips JSON marshalling of Body).
	// Useful for webhook ingestion endpoints that require signature verification over the exact bytes.
	RawBody     []byte
	Query       map[string]string
	Headers     map[string]string
	UseAdminKey bool
	Idempotent  bool // If true, can be retried for POST
}

Request represents an HTTP request to be made.

type Response

type Response struct {
	StatusCode int
	Body       []byte
	Headers    http.Header
	RequestID  string
}

Response represents an HTTP response.

type RetryConfig

type RetryConfig struct {
	MaxRetries int
	BaseDelay  time.Duration
	MaxDelay   time.Duration
	Factor     float64
	Jitter     bool
}

RetryConfig configures retry behavior.

func DefaultRetryConfig

func DefaultRetryConfig() RetryConfig

DefaultRetryConfig returns the default retry configuration.

type RetryPolicy

type RetryPolicy struct {
	MaxRetries int
	BaseDelay  time.Duration
	MaxDelay   time.Duration
	Factor     float64
	Jitter     bool
	// contains filtered or unexported fields
}

RetryPolicy implements exponential backoff with optional jitter.

func NewRetryPolicy

func NewRetryPolicy(cfg RetryConfig) *RetryPolicy

NewRetryPolicy creates a new retry policy.

func (*RetryPolicy) Delay

func (p *RetryPolicy) Delay(attempt int) time.Duration

Delay calculates the delay for a given retry attempt (0-indexed).

func (*RetryPolicy) DelayWithJitter

func (p *RetryPolicy) DelayWithJitter(attempt int, jitterFactor float64) time.Duration

DelayWithJitter calculates delay with deterministic jitter for testing.

func (*RetryPolicy) ShouldRetry

func (p *RetryPolicy) ShouldRetry(attempt int) bool

ShouldRetry returns true if we haven't exhausted retry attempts.

type ServerError

type ServerError struct{ *APIError }

ServerError represents a 5xx error.

func (*ServerError) IsRetryable

func (e *ServerError) IsRetryable() bool

IsRetryable always returns true for server errors.

func (*ServerError) Unwrap

func (e *ServerError) Unwrap() error

Unwrap returns the underlying API error.

type TimeoutError

type TimeoutError struct {
	*APIError
	TimeoutSeconds float64
}

TimeoutError represents a timeout error.

func NewTimeoutError

func NewTimeoutError(timeout time.Duration, err error) *TimeoutError

NewTimeoutError creates a new timeout error.

func (*TimeoutError) IsRetryable

func (e *TimeoutError) IsRetryable() bool

IsRetryable always returns true for timeout errors.

func (*TimeoutError) Unwrap

func (e *TimeoutError) Unwrap() error

Unwrap returns the underlying API error.

type TokenRefresher

type TokenRefresher struct {
	// contains filtered or unexported fields
}

TokenRefresher handles automatic token refresh.

func NewTokenRefresher

func NewTokenRefresher(baseURL, apiKey, refreshToken, accessToken string, logger Logger) *TokenRefresher

NewTokenRefresher creates a new token refresher.

func (*TokenRefresher) ForceRefresh

func (tr *TokenRefresher) ForceRefresh(ctx context.Context) error

ForceRefresh performs a token refresh regardless of expiry status. Used when receiving a 401 response.

func (*TokenRefresher) GetAccessToken

func (tr *TokenRefresher) GetAccessToken() string

GetAccessToken returns the current access token.

func (*TokenRefresher) NeedsRefresh

func (tr *TokenRefresher) NeedsRefresh() bool

NeedsRefresh returns true if the token needs to be refreshed.

func (*TokenRefresher) Refresh

func (tr *TokenRefresher) Refresh(ctx context.Context) error

Refresh performs a token refresh with single-flight coordination. Only one goroutine will actually perform the refresh; others will wait for it.

func (*TokenRefresher) RefreshIfNeeded

func (tr *TokenRefresher) RefreshIfNeeded(ctx context.Context) error

RefreshIfNeeded refreshes the token if it's expired or about to expire. Uses single-flight to prevent multiple concurrent refreshes.

func (*TokenRefresher) SetAccessToken

func (tr *TokenRefresher) SetAccessToken(token string, expiresIn int)

SetAccessToken updates the access token.

func (*TokenRefresher) SetRefreshToken

func (tr *TokenRefresher) SetRefreshToken(token string)

SetRefreshToken updates the refresh token.

type Transport

type Transport struct {
	// contains filtered or unexported fields
}

Transport wraps an http.Client with retry, circuit breaker, and auth handling.

func NewTransport

func NewTransport(cfg Config) *Transport

NewTransport creates a new Transport with the given configuration.

func (*Transport) Do

func (t *Transport) Do(ctx context.Context, req *Request) (*Response, error)

Do executes an HTTP request with retry and circuit breaker logic.

func (*Transport) SetAccessToken

func (t *Transport) SetAccessToken(token string)

SetAccessToken updates the access token (used for token refresh).

func (*Transport) SetRefreshToken

func (t *Transport) SetRefreshToken(token string)

SetRefreshToken updates the refresh token.

type ValidationError

type ValidationError struct{ *APIError }

ValidationError represents a 400/422 error.

func (*ValidationError) Unwrap

func (e *ValidationError) Unwrap() error

Unwrap returns the underlying API error.

Jump to

Keyboard shortcuts

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