client

package
v0.7.0-rc.2 Latest Latest
Warning

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

Go to latest
Published: Jun 2, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package client is a small fluent HTTP client:

The package depends only on the Go standard library and does not import the okapi server package, so it can be used against any REST API.

Basic usage:

c := client.New("https://api.example.com",
    client.WithHeader("X-Api-Version", "2025-05-01"),
    client.WithBearerToken(token),
    client.WithTimeout(10*time.Second),
)

var user User
resp, err := c.Get("/users/42").
    WithContext(ctx).
    QueryParam("expand", "profile").
    Do()
if err != nil {
    return err
}
if err := resp.Error(); err != nil {
    return err
}
if err := resp.JSON(&user); err != nil {
    return err
}

Do issues the request; Send is an alias for it. Decode is a shortcut that runs Do and decodes a 2xx response into a target value, choosing the format from the response Content-Type.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

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

Client is a reusable HTTP client bound to a base URL with default headers, middleware, and retry policy. It is safe for concurrent use.

func New

func New(baseURL string, opts ...Option) *Client

New returns a Client rooted at baseURL with the supplied options applied. The baseURL may be empty when callers always pass absolute URLs.

func (*Client) BaseURL

func (c *Client) BaseURL() string

BaseURL returns the client's base URL.

func (*Client) Delete

func (c *Client) Delete(path string) *RequestBuilder

Delete starts a DELETE request builder.

func (*Client) Do

func (c *Client) Do(ctx context.Context, req *http.Request) (*Response, error)

Do dispatches a fully prepared *http.Request through the client middleware chain and returns the read Response. Provided for callers that need full control over request construction.

func (*Client) Get

func (c *Client) Get(path string) *RequestBuilder

Get starts a GET request builder against baseURL+path.

func (*Client) Head

func (c *Client) Head(path string) *RequestBuilder

Head starts a HEAD request builder.

func (*Client) Options

func (c *Client) Options(path string) *RequestBuilder

Options starts an OPTIONS request builder.

func (*Client) Patch

func (c *Client) Patch(path string) *RequestBuilder

Patch starts a PATCH request builder.

func (*Client) Post

func (c *Client) Post(path string) *RequestBuilder

Post starts a POST request builder.

func (*Client) Put

func (c *Client) Put(path string) *RequestBuilder

Put starts a PUT request builder.

func (*Client) Request

func (c *Client) Request(method, path string) *RequestBuilder

Request starts a builder for an arbitrary HTTP method.

type HTTPError

type HTTPError struct {
	StatusCode int
	Status     string
	Method     string
	URL        string
	Body       []byte
	Header     http.Header
}

HTTPError represents a non-2xx HTTP response surfaced as an error. It is returned by Response.Error and never by Send itself, so callers can opt into treating non-2xx as an error or handle the response directly.

func (*HTTPError) Error

func (e *HTTPError) Error() string

type Middleware

type Middleware func(next RoundTripFunc) RoundTripFunc

Middleware wraps a RoundTripFunc to observe or modify requests/responses. Middlewares should call next exactly once unless they short-circuit on purpose (e.g. caching).

func LoggingMiddleware

func LoggingMiddleware(w io.Writer) Middleware

LoggingMiddleware logs one line per request to w with the method, URL, response status, and duration. It uses a fixed format suitable for development; production users typically supply their own.

func RequestIDMiddleware

func RequestIDMiddleware() Middleware

RequestIDMiddleware ensures an X-Request-Id header is set on every request, generating a random 16-byte hex value when the caller did not supply one.

func UserAgentMiddleware

func UserAgentMiddleware(ua string) Middleware

UserAgentMiddleware sets the User-Agent header on every outgoing request, overwriting any value previously set.

type Option

type Option func(*Client)

Option configures a Client. Options are applied in order, so later options can override earlier ones.

func WithBasicAuth

func WithBasicAuth(username, password string) Option

WithBasicAuth sets the default Authorization header using HTTP Basic auth.

func WithBearerToken

func WithBearerToken(token string) Option

WithBearerToken sets the default Authorization header to "Bearer <token>".

func WithHTTPClient

func WithHTTPClient(h *http.Client) Option

WithHTTPClient sets the underlying *http.Client used to dispatch requests. The client's Transport is wrapped with the configured middleware chain when the Client is used.

func WithHeader

func WithHeader(key, value string) Option

WithHeader sets a default header sent on every request.

func WithHeaders

func WithHeaders(headers map[string]string) Option

WithHeaders sets multiple default headers in one call.

func WithMiddleware

func WithMiddleware(mw ...Middleware) Option

WithMiddleware appends middleware to the client's chain. Middleware runs in registration order, with the first registered being the outermost wrapper.

func WithRetry

func WithRetry(p RetryPolicy) Option

WithRetry sets the default retry policy for every request.

func WithTimeout

func WithTimeout(d time.Duration) Option

WithTimeout sets the default per-request timeout. It is applied to every request unless the request builder overrides it via RequestBuilder.Timeout.

func WithUserAgent

func WithUserAgent(ua string) Option

WithUserAgent sets the default User-Agent header.

type RequestBuilder

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

RequestBuilder builds a single HTTP request. Most builder methods return the same builder for fluent chaining; Send is the terminal call that issues the request and returns the response.

func (*RequestBuilder) BasicAuth

func (rb *RequestBuilder) BasicAuth(username, password string) *RequestBuilder

BasicAuth sets the Authorization header using HTTP Basic auth.

func (*RequestBuilder) BearerToken

func (rb *RequestBuilder) BearerToken(token string) *RequestBuilder

BearerToken sets the Authorization header to "Bearer <token>".

func (*RequestBuilder) Body

func (rb *RequestBuilder) Body(body io.Reader) *RequestBuilder

Body sets a raw body reader. The caller controls Content-Type via Header.

func (*RequestBuilder) Decode

func (rb *RequestBuilder) Decode(target any) error

Decode is a shortcut for Do followed by Response.Decode into target, which selects the format from the response Content-Type. When the response is not 2xx it returns the *HTTPError without attempting to decode the body.

func (*RequestBuilder) Do

func (rb *RequestBuilder) Do() (*Response, error)

Do issues the request and returns the response. The response body is fully read into memory before Do returns. Send is an alias for Do.

func (*RequestBuilder) FormBody

func (rb *RequestBuilder) FormBody(values map[string]string) *RequestBuilder

FormBody encodes values as application/x-www-form-urlencoded.

func (*RequestBuilder) Header

func (rb *RequestBuilder) Header(key, value string) *RequestBuilder

Header sets a single request header, overwriting any existing value.

func (*RequestBuilder) Headers

func (rb *RequestBuilder) Headers(headers map[string]string) *RequestBuilder

Headers merges multiple headers into the request, overwriting on conflicts.

func (*RequestBuilder) JSONBody

func (rb *RequestBuilder) JSONBody(v any) *RequestBuilder

JSONBody marshals v as JSON and sets the Content-Type to application/json. If v is a string or []byte it is used verbatim.

func (*RequestBuilder) Middleware

func (rb *RequestBuilder) Middleware(mw ...Middleware) *RequestBuilder

Middleware appends middleware applied only to this request, after the client's middlewares.

func (*RequestBuilder) Multipart

func (rb *RequestBuilder) Multipart(build func(*multipart.Writer) error) *RequestBuilder

Multipart builds a multipart/form-data body using the supplied callback. The callback receives a *multipart.Writer that callers use to add fields and files. The writer is closed automatically once the callback returns.

func (*RequestBuilder) Path

func (rb *RequestBuilder) Path(path string) *RequestBuilder

Path appends a path segment to the request URL.

func (*RequestBuilder) QueryParam

func (rb *RequestBuilder) QueryParam(key, value string) *RequestBuilder

QueryParam appends a single query string parameter. Multiple calls with the same key produce multi-value query parameters.

func (*RequestBuilder) QueryParams

func (rb *RequestBuilder) QueryParams(params map[string]string) *RequestBuilder

QueryParams adds multiple query parameters in one call.

func (*RequestBuilder) RawBody

func (rb *RequestBuilder) RawBody(b []byte) *RequestBuilder

RawBody sets a raw byte slice as the request body.

func (*RequestBuilder) Retry

Retry overrides the retry policy for this call.

func (*RequestBuilder) Send

func (rb *RequestBuilder) Send() (*Response, error)

Send issues the request and returns the response. It is an alias for Do, provided for callers who prefer the verb.

func (*RequestBuilder) Timeout

func (rb *RequestBuilder) Timeout(d time.Duration) *RequestBuilder

Timeout overrides the per-request timeout for this call.

func (*RequestBuilder) WithContext

func (rb *RequestBuilder) WithContext(ctx context.Context) *RequestBuilder

WithContext attaches a context to the request. Defaults to context.Background.

func (*RequestBuilder) XMLBody

func (rb *RequestBuilder) XMLBody(v any) *RequestBuilder

XMLBody marshals v as XML and sets the Content-Type to application/xml.

func (*RequestBuilder) YAMLBody

func (rb *RequestBuilder) YAMLBody(v any) *RequestBuilder

YAMLBody marshals v as YAML and sets the Content-Type to application/yaml.

type Response

type Response struct {
	*http.Response

	// Body is the fully read response payload.
	Body []byte
	// Method is the HTTP method used by the originating request.
	Method string
	// URL is the final request URL.
	URL string
}

Response wraps *http.Response with an already-read body and decode helpers. The original response body is closed by the time Response is returned, so callers should use Body or the typed decoders.

func (*Response) Cookie

func (r *Response) Cookie(name string) *http.Cookie

Cookie returns the named cookie set by the server, or nil if not present.

func (*Response) Decode

func (r *Response) Decode(target any) error

Decode unmarshals the body into target, choosing the format from the response Content-Type header: an "xml" content type decodes as XML, a "yaml" content type decodes as YAML, and anything else decodes as JSON. Use JSON, XML, or YAML directly when explicit control is needed.

func (*Response) Error

func (r *Response) Error() error

Error returns an *HTTPError describing the response when the status is not 2xx, and nil otherwise.

func (*Response) IsSuccess

func (r *Response) IsSuccess() bool

IsSuccess reports whether the status code is in [200, 300).

func (*Response) JSON

func (r *Response) JSON(target any) error

JSON decodes the body into target as JSON.

func (*Response) JSONPath

func (r *Response) JSONPath(path string) (any, bool)

JSONPath returns the value at the dot-separated path within a JSON object body. It returns ok=false if the body is not a JSON object or the path does not resolve.

func (*Response) String

func (r *Response) String() string

String returns the body as a string.

func (*Response) XML

func (r *Response) XML(target any) error

XML decodes the body into target as XML.

func (*Response) YAML

func (r *Response) YAML(target any) error

YAML decodes the body into target as YAML.

type RetryPolicy

type RetryPolicy struct {
	// MaxAttempts is the total number of attempts including the first one.
	// Values <= 1 disable retries.
	MaxAttempts int

	// BaseDelay is the initial delay before the second attempt. Subsequent
	// attempts double the delay (exponential backoff) up to MaxDelay.
	BaseDelay time.Duration

	// MaxDelay caps the backoff delay. If zero, the delay grows unbounded.
	MaxDelay time.Duration

	// RetryOnStatus lists HTTP response status codes that trigger a retry.
	// Defaults to 408, 429, 500, 502, 503, 504 when nil and MaxAttempts > 1.
	RetryOnStatus []int

	// ShouldRetry, if non-nil, is consulted in addition to RetryOnStatus.
	// It receives the response (may be nil) and any transport error and
	// returns true to retry. It overrides RetryOnStatus when set.
	ShouldRetry func(resp *http.Response, err error) bool
}

RetryPolicy controls how the retry middleware behaves. The zero value disables retries (MaxAttempts <= 1).

type RoundTripFunc

type RoundTripFunc func(*http.Request) (*http.Response, error)

RoundTripFunc is the function form of an http.RoundTripper used to compose the client middleware chain.

func (RoundTripFunc) RoundTrip

func (f RoundTripFunc) RoundTrip(r *http.Request) (*http.Response, error)

RoundTrip implements http.RoundTripper.

Jump to

Keyboard shortcuts

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