httpc

package module
v0.3.2 Latest Latest
Warning

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

Go to latest
Published: Jun 10, 2026 License: MIT Imports: 14 Imported by: 0

README

httpc

Simple wrapping of the existing http.Client with some additional functionality.

How to use

stdlib compatibility

As the client extends a *http.Client you can use the existing functionality as defined in the stdlib.

client := httpc.New()

resp, err := client.Get("example.com")
... // handle the response and error

resp, err := client.Do(req)
...

underlyingClient := client.Unwrap() // of type *http.Client
// pass this to calls that require type *http.Client
// still contains all layers of http.RoundTripper
Extensions

Beyond the existing functions of the stdlib http client there are few convenience wrappers in place to help reduce repetitive coding tasks. All outgoing calls DoReq(), JSON() and Stream() close the response's body and replace it with a NopCloser.

client := httpc.New(WithTimeout(10 * time.Second)) // optional options can be passed to the initial setup
h := http.Header{}
h.Set("key", "value")
client.AddOptions(WithHeaders(h)) // further options can be added

resp, err := client.DoReq(req, WithStatusCode(http.StatusOk)) // call like Do() with additional check of the status code
...

type Person struct {
	FirstName string `json:"firstName"`
	LastName string `json:"lastName"`
}

var p Person
resp, err := client.JSON(req, &p, WithStatusCode(http.StatusOk)) // decodes the response to the given pointer
...

f, _ := os.OpenFile("data.out", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
written, err := client.Stream(req, f) // stream the response to a file
...
Error Handling

Only additional functionality calls do support error handling. For HTTP status codes above 400 the error handler is called. By default, the response body is read as is and be added to the error message. See the examples below to add custom error types.

client := httpc.New(WithJSONError())

_, err := client.DoReq(req) // if fails, attempts to parse response body as arbitrary JSON
// err should be of type JSONErrorBody map[string]any
// can be used to access error details

type ApiError struct {
	Code int `json:"code"`
	Msg string `json:"msg"`
}

client := httpc.New(WithCustomJSONError[ApiError]())

_, err := client.DoReq(req) // if fails, attempts to parse response body as given error
// err should be of type ApiError

Documentation

Index

Constants

View Source
const DefaultTimeout = 30 * time.Second

Variables

View Source
var DefaultTransport = &http.Transport{
	Proxy:                 http.ProxyFromEnvironment,
	ForceAttemptHTTP2:     true,
	MaxIdleConns:          100,
	IdleConnTimeout:       90 * time.Second,
	TLSHandshakeTimeout:   10 * time.Second,
	ExpectContinueTimeout: 1 * time.Second,
}

Functions

This section is empty.

Types

type BytesBodyError added in v0.3.0

type BytesBodyError []byte

BytesBodyError raw []byte representation of an HTTP body.

func (BytesBodyError) Error added in v0.3.0

func (e BytesBodyError) Error() string

type Client

type Client struct {
	*http.Client
	// contains filtered or unexported fields
}

Client the HTTP client wraps an existing http.Client with some helper function. Can be used as a regular http.Client. All Layer will be applied to the underlying client and therefore will be executed even for calls such as Do() or Get(). Call Unwrap to get the underlying client to use it as a regular http.Client.

func New

func New(opts ...ClientOption) *Client

New creates a new Client with the defaults in Config. More ClientOption can be provided to adjust the default config.

func (*Client) AddOptions

func (c *Client) AddOptions(opts ...ClientOption)

AddOptions add more options to the current Client.

func (*Client) Close added in v0.3.0

func (c *Client) Close() error

Close will close all shutdown hooks attached to Config.Shutdowns and return the combined error. The Client should not be used after calling this function.

func (*Client) DoReq

func (c *Client) DoReq(req *http.Request, opts ...RespOption) (*http.Response, error)

DoReq wraps the standard implementation of Do(). The response body is read in full and will be closed. For non-closed http.Response see Do or Stream. Both the http.Response and the read in body serve as input for the given RespOption.

func (*Client) Extend

func (c *Client) Extend(opts ...ClientOption) *Client

Extend creates a new Client based on the Config of the current with the optional given ClientOption.

func (*Client) JSON

func (c *Client) JSON(req *http.Request, obj any, opts ...RespOption) (*http.Response, error)

JSON is a wrapper for DoReq in combination with the WithJSON option.

func (*Client) Stream

func (c *Client) Stream(req *http.Request, w io.Writer) (int64, error)

Stream wraps a Do call and copies the http.Response body to the given io.Writer.

func (*Client) Unwrap

func (c *Client) Unwrap() *http.Client

Unwrap returns the underlying http.Client to use with http.RoundTripper applied

type ClientOption added in v0.3.0

type ClientOption func(cfg *Config)

ClientOption function to modify the Config when creating or updating a Client.

func WithCheckRedirect

func WithCheckRedirect(fn func(req *http.Request, via []*http.Request) error) ClientOption

WithCheckRedirect sets the redirect function for the http.Client. Defaults to nil.

func WithCookieJar

func WithCookieJar(jar http.CookieJar) ClientOption

WithCookieJar sets the cookie jar implementation for the http.Client. Defaults to nil.

func WithH3Transport added in v0.3.0

func WithH3Transport(t *http3.Transport) ClientOption

WithH3Transport sets an optional h3 transport to use for HTTP 3 UDP connections. This is an experimental feature.

func WithHeaders

func WithHeaders(h http.Header) ClientOption

WithHeaders adds the given headers to every outgoing call by default.

func WithHttp3 added in v0.3.0

func WithHttp3() ClientOption

WithHttp3 sets WithH3Transport with an empty http3.Transport. This is an experimental feature.

func WithLayer

func WithLayer(l Layer) ClientOption

WithLayer adds a new Layer to the stack of layers executed for every HTTP request.

func WithMemoryPooling added in v0.3.0

func WithMemoryPooling() ClientOption

WithMemoryPooling enables the memory pooling feature to reuse byte slices to read in HTTP bodies. This might reduce pressure on the garbage collector.

func WithRespOption added in v0.3.0

func WithRespOption(opt RespOption) ClientOption

WithRespOption adds a default response option used in every Client.DoReq call before the furtherly passed response options.

func WithTimeout

func WithTimeout(t time.Duration) ClientOption

WithTimeout sets the timeout used for every HTTP request. Defaults to DefaultTimeout.

func WithTransport

func WithTransport(t *http.Transport) ClientOption

WithTransport sets the http.Transport user for every HTTP request. Defaults to DefaultTransport.

type Config

type Config struct {
	// Transport a pointer to the underlying http.Transport. This is used as
	// the base for the http.Client and the http.RoundTripper. Defaults to
	// DefaultTransport. Can be set via WithTransport.
	Transport *http.Transport
	// H3Transport is an optional pointer to a http3.Transport. If this is
	// set the Client attempts to try h3 connections first. Based on the domain
	// the Client stores if the domain supports h3 or not. Can be set via
	// WithH3Transport.
	H3Transport *http3.Transport
	// CheckRedirect redirecting logic as defined in the http.Client to
	// determine redirects. Defaults to nil. Can be set via WithCheckRedirect.
	CheckRedirect func(req *http.Request, via []*http.Request) error
	// Jar the cookie storage logic of the http.CookieJar to be used by the
	// http.Client. Defaults to nil. Can be set via WithCookieJar.
	Jar http.CookieJar
	// Timeout for each outgoing HTTP request. A value of 0 means no timeout.
	// Defaults to DefaultTimeout. Can be set via WithTimeout.
	Timeout time.Duration
	// MemoryPooling enables the use of a memory pool to hold buffers for
	// reading in the HTTP bodies. This feature can result in performance
	// increases but does not set the http.Response body back after reading.
	// Defaults to false. Can be set via WithMemoryPooling.
	MemoryPooling bool
	// Shutdowns slice of shutdown functions executed on Client.Close call.
	Shutdowns []func() error
	// contains filtered or unexported fields
}

Config struct holding all the configurations of an HTTP Client. Can be modified via the With* options.

type JSONBodyError added in v0.3.0

type JSONBodyError map[string]any

JSONBodyError arbitrary JSON representation of an HTTP body.

func (JSONBodyError) Error added in v0.3.0

func (e JSONBodyError) Error() string

type Layer

type Layer func(base http.RoundTripper) http.RoundTripper

Layer is a function that wraps one http.RoundTripper into the next. The given base must be executed.

type RespOption

type RespOption func(resp *http.Response, body []byte) error

RespOption is an option to handle a successful http.Response pointer. Aborts if the first option returns an error. The response's body is already read and closed. The read data is passed as parameter. The body parameter should not be stored, but rather copied if needed. It must not be stored in combination with the WithMemoryPooling Option.

func WithBytesError

func WithBytesError() RespOption

WithBytesError returns a BytesBodyError if the HTTP call failed. Represents a raw []byte body.

func WithCopy

func WithCopy(w io.Writer) RespOption

WithCopy copies the body of the http.Response to the given io.Writer.

func WithCustomJSONError

func WithCustomJSONError[E error]() RespOption

WithCustomJSONError returns an error of the given type E. Must implement the error interface. Will use the json.Unmarshal to read in the HTTP response's body.

func WithJSON

func WithJSON(obj any) RespOption

WithJSON unmarshalls the body of a successful http.Response into the given object using the json.Unmarshal function.

func WithJSONError

func WithJSONError() RespOption

WithJSONError wraps WithCustomJSONError with the JSONBodyError type. Allows generic JSON data as error struct.

func WithNon2xxError added in v0.3.0

func WithNon2xxError() RespOption

WithNon2xxError is WithStatusCodeRange with the 2xx HTTP status code range.zxl

func WithStatusCode

func WithStatusCode(code int) RespOption

WithStatusCode checks if the http.Response matches the given HTTP status code. Returns an error if the status code does not match.

func WithStatusCodeRange added in v0.3.0

func WithStatusCodeRange(lower, upper int) RespOption

WithStatusCodeRange checks if the HTTP response code is within the lower (inclusive) and the upper (exclusive). Returns an error if not.

Jump to

Keyboard shortcuts

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