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 ¶
- type Client
- func (c *Client) BaseURL() string
- func (c *Client) Delete(path string) *RequestBuilder
- func (c *Client) Do(ctx context.Context, req *http.Request) (*Response, error)
- func (c *Client) Get(path string) *RequestBuilder
- func (c *Client) Head(path string) *RequestBuilder
- func (c *Client) Options(path string) *RequestBuilder
- func (c *Client) Patch(path string) *RequestBuilder
- func (c *Client) Post(path string) *RequestBuilder
- func (c *Client) Put(path string) *RequestBuilder
- func (c *Client) Request(method, path string) *RequestBuilder
- type HTTPError
- type Middleware
- type Option
- func WithBasicAuth(username, password string) Option
- func WithBearerToken(token string) Option
- func WithHTTPClient(h *http.Client) Option
- func WithHeader(key, value string) Option
- func WithHeaders(headers map[string]string) Option
- func WithMiddleware(mw ...Middleware) Option
- func WithRetry(p RetryPolicy) Option
- func WithTimeout(d time.Duration) Option
- func WithUserAgent(ua string) Option
- type RequestBuilder
- func (rb *RequestBuilder) BasicAuth(username, password string) *RequestBuilder
- func (rb *RequestBuilder) BearerToken(token string) *RequestBuilder
- func (rb *RequestBuilder) Body(body io.Reader) *RequestBuilder
- func (rb *RequestBuilder) Decode(target any) error
- func (rb *RequestBuilder) Do() (*Response, error)
- func (rb *RequestBuilder) FormBody(values map[string]string) *RequestBuilder
- func (rb *RequestBuilder) Header(key, value string) *RequestBuilder
- func (rb *RequestBuilder) Headers(headers map[string]string) *RequestBuilder
- func (rb *RequestBuilder) JSONBody(v any) *RequestBuilder
- func (rb *RequestBuilder) Middleware(mw ...Middleware) *RequestBuilder
- func (rb *RequestBuilder) Multipart(build func(*multipart.Writer) error) *RequestBuilder
- func (rb *RequestBuilder) Path(path string) *RequestBuilder
- func (rb *RequestBuilder) QueryParam(key, value string) *RequestBuilder
- func (rb *RequestBuilder) QueryParams(params map[string]string) *RequestBuilder
- func (rb *RequestBuilder) RawBody(b []byte) *RequestBuilder
- func (rb *RequestBuilder) Retry(p RetryPolicy) *RequestBuilder
- func (rb *RequestBuilder) Send() (*Response, error)
- func (rb *RequestBuilder) Timeout(d time.Duration) *RequestBuilder
- func (rb *RequestBuilder) WithContext(ctx context.Context) *RequestBuilder
- func (rb *RequestBuilder) XMLBody(v any) *RequestBuilder
- func (rb *RequestBuilder) YAMLBody(v any) *RequestBuilder
- type Response
- func (r *Response) Cookie(name string) *http.Cookie
- func (r *Response) Decode(target any) error
- func (r *Response) Error() error
- func (r *Response) IsSuccess() bool
- func (r *Response) JSON(target any) error
- func (r *Response) JSONPath(path string) (any, bool)
- func (r *Response) String() string
- func (r *Response) XML(target any) error
- func (r *Response) YAML(target any) error
- type RetryPolicy
- type RoundTripFunc
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 ¶
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) Delete ¶
func (c *Client) Delete(path string) *RequestBuilder
Delete starts a DELETE request builder.
func (*Client) Do ¶
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.
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 ¶
WithBasicAuth sets the default Authorization header using HTTP Basic auth.
func WithBearerToken ¶
WithBearerToken sets the default Authorization header to "Bearer <token>".
func WithHTTPClient ¶
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 ¶
WithHeader sets a default header sent on every request.
func WithHeaders ¶
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 ¶
WithTimeout sets the default per-request timeout. It is applied to every request unless the request builder overrides it via RequestBuilder.Timeout.
func WithUserAgent ¶
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 ¶
func (rb *RequestBuilder) Retry(p RetryPolicy) *RequestBuilder
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) Decode ¶
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 ¶
Error returns an *HTTPError describing the response when the status is not 2xx, and nil otherwise.
func (*Response) JSONPath ¶
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.
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 ¶
RoundTripFunc is the function form of an http.RoundTripper used to compose the client middleware chain.