cmhttp

package module
v0.0.0-...-b529ae0 Latest Latest
Warning

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

Go to latest
Published: Feb 20, 2023 License: Unlicense Imports: 13 Imported by: 0

README

Composable HTTP client decorators

Simple Usage
client := cmhttp.Decorate(
    http.DefaultClient,
    cmhttp.Scoped("https://api.example.com"),
    cmhttp.Typed("application/json"), // or cmhttp.JSON()
)

req, err := http.NewRequest("GET", "/v1/places/de.berlin", nil)
if err != nil {
    panic(err)
}

resp, err := client.Do(req)
Configuring TLS
baseClient := &http.Client{
    Transport: &http.Transport{},
}
cmhttp.MustConfigureTLS(baseClient.Transport.(*http.Transport), "/etc/ssl/cabundle.pem")

client := cmhttp.Decorate(
    baseClient,
    cmhttp.Scoped("https://api.example.com"),
    cmhttp.Typed("application/json"), // or cmhttp.JSON()
)
Implementing custom decorators:
import (
    "log"
    "net/http"
    "os"
    "time"
)

func Logged(log *log.Logger) Decorator {
    return func(c Client) Client {
        return ClientFunc(func(r *http.Request) (*http.Response, error) {
            var (
                resp *http.Response
                err error
            )

            defer func(begin time.Time) {
                log.Printf(
                    "method=%s url=%s resp=%d err=%s took=%dms",
                    r.Method, r.URL, resp.StatusCode, err, time.Since(begin)/1e6,
                )
            }(time.Now())

            resp, err = c.Do(r)
            return resp, err
        })
    }   
}

Use it:

logger := log.New(os.Stdout, "my-service: ", log.LstdFlags)
client := Logged(logger)(http.DefaultClient)

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ConfigureTLS

func ConfigureTLS(t *http.Transport, rootCertsFilePath string) error

ConfigureTLS reads the certificate bundle at rootCertsFilePath and configures the given transport to verify server certificate against these certificates.

func DrainClose

func DrainClose(body io.ReadCloser) error

DrainClose reads up to 256 kB from body and then calls Close. If draining the body returns a non-nil error other than io.EOF, that error is returned. Otherwise the error from Close() is returned. Close() is called even if draining fails.

If body is nil, DrainClose returns a nil error immediately.

func MustConfigureTLS

func MustConfigureTLS(t *http.Transport, rootCertsFilePath string)

MustConfigureTLS is the same as ConfigureTLS, but panics if there is an error.

Types

type Client

type Client interface {
	Do(*http.Request) (*http.Response, error)
}

A Client sends http.Requests and returns http.Responses or errors in case of failure. Responses with StatusCode >= 400 are *not* considered a failure.

func Decorate

func Decorate(c Client, ds ...Decorator) Client

Decorate wraps a Client with all the given Decorators, in order.

type ClientFunc

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

ClientFunc is a function type that implements the Client interface.

func (ClientFunc) Do

func (f ClientFunc) Do(r *http.Request) (*http.Response, error)

Do executes this function with the given request as input and returns all results without changing them.

type Decorator

type Decorator func(Client) Client

A Decorator wraps a Client with additional behaviour or capabilities.

func BasicAuth

func BasicAuth(username, password string) Decorator

BasicAuth sets all request's Authorization header to use HTTP Basic Authentication with the provided username and password.

With HTTP Basic Authentication the provided username and password are not encrypted.

func FaultTolerant

func FaultTolerant(attempts int, backoff time.Duration) Decorator

FaultTolerant retries requests that failed do to network errors attempts times, and sleeps for increasing amounts of time between attempts. If all attempts fail, the last error is returned.

func Instrumented

func Instrumented(name string) Decorator

Instrumented registers and collects the following four metrics with the default Registerer:

  • http_client_requests_total (CounterVec)
  • http_client_request_duration_seconds (Summary),
  • http_client_request_size_bytes (Summary)
  • http_client_response_size_bytes (Summary)

Each has a constant label named "name" with the provided name as value. http_client_requests_total is a metric vector partitioned by HTTP method ("method" label) and HTTP status code ("code" label).

This code closely resembles the HTTP server side prometheus.InstrumentHandler function.

func InstrumentedRequestDurations

func InstrumentedRequestDurations(opts prometheus.HistogramOpts) Decorator

InstrumentedRequestDurations instruments the client by tracking the request durations as histogram vector partitioned by HTTP method (label name "method") and response code (label name "code").

InstrumentedRequestDurations will set the Name and Help fields of opts.

func InstrumentedWithOpts

func InstrumentedWithOpts(opts prometheus.SummaryOpts) Decorator

InstrumentedWithOpts is like Instrumented but allows changing Namespace ("" by default) and/or Subsystem ("http_client" by default) and adding ConstLabels. All other fields of opts are ignored.

func JSON

func JSON() Decorator

JSON sets the Content-Type and Accept request headers to "application/json" (unless the requests already has non-empty headers).

func Logged

func Logged(logf func(string, ...interface{}), trigger func() bool) Decorator

Logged is used to execute a log function after the request has been made. Neither the request body nor the response body will be logged. If the client returned an error it will be logged as well.

func Null

func Null() Decorator

Null always returns a 204 No Content response without ever opening a network connection.

func Scoped

func Scoped(baseURL string) Decorator

Scoped resolves the Request's URL against the given baseURL before sending the request. If baseURL cannot be parsed, Scoped panics.

func ScopedURL

func ScopedURL(baseURL *url.URL) Decorator

ScopedURL resolves the Request's URL against the given baseURL before sending the request.

func StaticClientPool

func StaticClientPool(baseURLs []string, decayDuration time.Duration, valueCalculator hostpool.EpsilonValueCalculator) Decorator

StaticClientPool creates a pool of HTTP clients that use an ε-greedy strategy to distribute HTTP requests among multiple hosts. The pool transparently distributes the requests among the hosts taking the individual request durations and failures into account.

The first parameter must be a list of absolute URLs that correspond to the hosts that should receive the client requests. If any of the given URLs is not valid or relative StaticClientPool will panic immediately instead of when the returned decorator is actually used.

A more detailed discussion of the underlying algorithm can be found at https://godoc.org/github.com/bitly/go-hostpool#NewEpsilonGreedy

See also https://en.wikipedia.org/wiki/Epsilon-greedy_strategy

func Typed

func Typed(contentType string) Decorator

Typed adds Content-Type and Accept request headers to the given value, unless the respective header is non-empty.

func WithHeader

func WithHeader(name, value string) Decorator

Jump to

Keyboard shortcuts

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