httpclient

package module
v1.4.0 Latest Latest
Warning

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

Go to latest
Published: Mar 15, 2024 License: MIT Imports: 3 Imported by: 1

README

Http Client Module

ci go report codecov Deps PkgGoDev

Http client module based on net/http.

Installation

go get github.com/ankorstore/yokai/httpclient

Documentation

To create a http.Client:

package main

import (
	"time"

	"github.com/ankorstore/yokai/httpclient"
	"github.com/ankorstore/yokai/httpclient/transport"
)

var client, _ = httpclient.NewDefaultHttpClientFactory().Create()

// equivalent to:
var client, _ = httpclient.NewDefaultHttpClientFactory().Create(
	httpclient.WithTransport(transport.NewBaseTransport()), // base http transport (optimized)
	httpclient.WithTimeout(30*time.Second),                 // 30 seconds timeout
	httpclient.WithCheckRedirect(nil),                      // default redirection checks
	httpclient.WithCookieJar(nil),                          // default cookie jar
)
Requests

This module provide some request helpers to ease client requests headers propagation from an incoming request:

  • CopyObservabilityRequestHeaders to copy x-request-id and traceparent headers
  • CopyRequestHeaders to choose a list of headers to copy

For example:

package main

import (
	"net/http"

	"github.com/ankorstore/yokai/httpclient"
)

func exampleHandler(w http.ResponseWriter, r *http.Request) {
	// create http client
	client, _ := httpclient.NewDefaultHttpClientFactory().Create()

	// build a request to send with the client
	rc, _ := http.NewRequest(http.MethodGet, "https://example.com", nil)

	// propagate observability headers: x-request-id and traceparent
	httpclient.CopyObservabilityRequestHeaders(r, rc)

	// client call
	resp, _ := client.Do(rc)

	// propagate response code
	w.WriteHeader(resp.StatusCode)
}

func main() {
	http.HandleFunc("/", exampleHandler)
	http.ListenAndServe(":8080", nil)
}
Transports
BaseTransport

This module provide a BaseTransport, optimized regarding max connections handling.

To use it:

package main

import (
	"github.com/ankorstore/yokai/httpclient"
	"github.com/ankorstore/yokai/httpclient/transport"
)

var client, _ = httpclient.NewDefaultHttpClientFactory().Create(
	httpclient.WithTransport(transport.NewBaseTransport()),
)

// equivalent to:
var client, _ = httpclient.NewDefaultHttpClientFactory().Create(
	httpclient.WithTransport(
		transport.NewBaseTransportWithConfig(&transport.BaseTransportConfig{
			MaxIdleConnections:        100,
			MaxConnectionsPerHost:     100,
			MaxIdleConnectionsPerHost: 100,
		}),
	),
)
LoggerTransport

This module provide a LoggerTransport, able to decorate any http.RoundTripper to add logging:

  • with requests and response details (and optionally body)
  • with configurable log level for each

To use it:

package main

import (
	"github.com/ankorstore/yokai/httpclient"
	"github.com/ankorstore/yokai/httpclient/transport"
	"github.com/rs/zerolog"
)

var client, _ = httpclient.NewDefaultHttpClientFactory().Create(
	httpclient.WithTransport(transport.NewLoggerTransport(nil)),
)

// equivalent to:
var client, _ = httpclient.NewDefaultHttpClientFactory().Create(
	httpclient.WithTransport(
		transport.NewLoggerTransportWithConfig(
			transport.NewBaseTransport(),
			&transport.LoggerTransportConfig{
				LogRequest:                       false,             // to log request details
				LogResponse:                      false,             // to log response details
				LogRequestBody:                   false,             // to log request body (if request details logging enabled)
				LogResponseBody:                  false,             // to log response body (if response details logging enabled)
				LogRequestLevel:                  zerolog.InfoLevel, // log level for request log
				LogResponseLevel:                 zerolog.InfoLevel, // log level for response log
				LogResponseLevelFromResponseCode: false,             // to use response code for response log level
			},
		),
	),
)

Note: if no transport is provided for decoration in transport.NewLoggerTransport(nil), the BaseTransport will be used as base transport.

MetricsTransport

This module provide a MetricsTransport, able to decorate any http.RoundTripper to add metrics:

  • about requests total count (labelled by url, http method and status code)
  • about requests duration (labelled by url and http method)

To use it:

package main

import (
	"github.com/ankorstore/yokai/httpclient"
	"github.com/ankorstore/yokai/httpclient/transport"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/rs/zerolog"
)

var client, _ = httpclient.NewDefaultHttpClientFactory().Create(
	httpclient.WithTransport(transport.NewMetricsTransport(nil)),
)

// equivalent to:
var client, _ = httpclient.NewDefaultHttpClientFactory().Create(
	httpclient.WithTransport(
		transport.NewMetricsTransportWithConfig(
			transport.NewBaseTransport(),
			&transport.MetricsTransportConfig{
				Registry:                  prometheus.DefaultRegisterer, // metrics registry
				Namespace:                 "",                           // metrics namespace
				Subsystem:                 "",                           // metrics subsystem
				Buckets:                   prometheus.DefBuckets,        // metrics duration buckets
				NormalizeRequestPath:      false,                        // normalize the request path following the masks given in NormalizePathMasks
				NormalizeRequestPathMasks: map[string]string{},          // request path normalization masks (key: regex to match, value: mask to apply)
				NormalizeResponseStatus:   true,                         // normalize the response HTTP code (ex: 201 => 2xx)
			},
		),
	),
)

If no transport is provided for decoration in transport.NewMetricsTransport(nil), the BaseTransport will be used as base transport.

If no registry is provided in the config in transport.NewMetricsTransportWithConfig(nil, config), the prometheus.DefaultRegisterer will be used a metrics registry

If the provided config provides NormalizeRequestPath to true and with the following NormalizeRequestPathMasks:

map[string]string{
    `/foo/(.+)/bar\?page=(.+)`: "/foo/{fooId}/bar?page={pageId}",
},

Then if the request path is /foo/1/bar?page=2, the metric path label will be masked with /foo/{fooId}/bar?page={pageId}.

Documentation

Index

Constants

View Source
const (
	HeaderXRequestId  = "x-request-id"
	HeaderTraceParent = "traceparent"
)

Variables

This section is empty.

Functions

func CopyObservabilityRequestHeaders

func CopyObservabilityRequestHeaders(source *http.Request, dest *http.Request)

CopyObservabilityRequestHeaders performs a copy of x-request-id and traceparent headers between two http.Request.

func CopyRequestHeaders

func CopyRequestHeaders(source *http.Request, dest *http.Request, headers ...string)

CopyRequestHeaders performs a copy of a specified list of headers between two http.Request.

Types

type DefaultHttpClientFactory

type DefaultHttpClientFactory struct{}

DefaultHttpClientFactory is the default HttpClientFactory implementation.

func (*DefaultHttpClientFactory) Create

func (f *DefaultHttpClientFactory) Create(options ...HttpClientOption) (*http.Client, error)

Create returns a new http.Client, and accepts a list of HttpClientOption. For example:

var client, _ = httpclient.NewDefaultHttpClientFactory().Create()

// equivalent to:
var client, _ = httpclient.NewDefaultHttpClientFactory().Create(
	httpclient.WithTransport(transport.NewBaseTransport()), // base http transport (optimized)
	httpclient.WithTimeout(30*time.Second),                 // 30 seconds timeout
	httpclient.WithCheckRedirect(nil),                      // default redirection checks
	httpclient.WithCookieJar(nil),                          // default cookie jar
)

type HttpClientFactory

type HttpClientFactory interface {
	Create(opts ...HttpClientOption) (*http.Client, error)
}

HttpClientFactory is the interface for http.Client factories.

func NewDefaultHttpClientFactory

func NewDefaultHttpClientFactory() HttpClientFactory

NewDefaultHttpClientFactory returns a DefaultHttpClientFactory, implementing HttpClientFactory.

type HttpClientOption

type HttpClientOption func(o *Options)

HttpClientOption are functional options for the HttpClientFactory implementations.

func WithCheckRedirect

func WithCheckRedirect(f func(req *http.Request, via []*http.Request) error) HttpClientOption

WithCheckRedirect is used to specify the check redirect func to use by the http.Client.

func WithCookieJar

func WithCookieJar(j http.CookieJar) HttpClientOption

WithCookieJar is used to specify the http.CookieJar to use by the http.Client.

func WithTimeout

func WithTimeout(t time.Duration) HttpClientOption

WithTimeout is used to specify the timeout to use by the http.Client.

func WithTransport

func WithTransport(t http.RoundTripper) HttpClientOption

WithTransport is used to specify the http.RoundTripper to use by the http.Client.

type Options

type Options struct {
	Transport     http.RoundTripper
	CheckRedirect func(req *http.Request, via []*http.Request) error
	Jar           http.CookieJar
	Timeout       time.Duration
}

Options are options for the HttpClientFactory implementations.

func DefaultHttpClientOptions

func DefaultHttpClientOptions() Options

DefaultHttpClientOptions are the default options used in the DefaultHttpClientFactory.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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