httpclient

package module
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Dec 2, 2022 License: MIT Imports: 10 Imported by: 2

README

httpclient

GitHub tag (latest by date) Codecov Test Go Report Card GitHub GoDoc

Basic HTTP client that I found myself writing over and over again.

Documentation

Authors

  • Christophe Lambin

License

This project is licensed under the MIT License - see the LICENSE.md file for details.

Documentation

Overview

Package httpclient provides a standard way of writing API clients. It's meant to be a drop-in replacement for an HTTPClient. Currently, it supports generating Prometheus metrics when performing API calls, and caching API responses.

InstrumentedClient generates Prometheus metrics when performing API calls. Currently, it records request latency and errors.

Cacher caches responses to HTTP requests, based on the provided CacheTableEntry slice. If the slice is empty, all responses will be cached.

Note: NewCacher will create a Caller that also generates Prometheus metrics by chaining the request to an InstrumentedClient. To avoid this, create a Cacher object directly:

c := &httpclient.Cacher{
	Caller: &httpclient.BaseClient{},
	Table: httpclient.CacheTable{Table: cacheEntries},
	Cache: cache.New[string, []byte](cacheExpiry, cacheCleanup),

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type BaseClient

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

BaseClient performs the actual HTTP request

func (*BaseClient) Do

func (b *BaseClient) Do(req *http.Request) (resp *http.Response, err error)

Do performs the actual HTTP request

type CacheTable

type CacheTable struct {
	Table []CacheTableEntry
	// contains filtered or unexported fields
}

CacheTable holds the Endpoints that should be cached. If Table is empty, all responses will be cached.

type CacheTableEntry

type CacheTableEntry struct {
	// Endpoint is the URL Path for requests whose responses should be cached.
	// Can be a literal path, or a regular expression. In the latter case,
	// set IsRegExp to true
	Endpoint string
	// Methods is the list of HTTP Methods for which requests the response should be cached.
	// If empty, requests for any method will be cached.
	Methods []string
	// IsRegExp indicated the Endpoint is a regular expression.
	// Note: CacheTableEntry will panic if Endpoint does not contain a valid regular expression.
	IsRegExp bool
	// Expiry indicates how long a response should be cached.
	Expiry time.Duration
	// contains filtered or unexported fields
}

CacheTableEntry contains a single endpoint that should be cached. If the Endpoint is a regular expression, IsRegExp must be set. CacheTable will then compile it when needed. CacheTable will panic if the regular expression is invalid.

type Cacher

type Cacher struct {
	Caller
	Table CacheTable
	Cache cache.Cacher[string, []byte]
}

Cacher will cache calls based in the provided CacheTable

Example
package main

import (
	"fmt"
	"github.com/clambin/httpclient"
	"github.com/prometheus/client_golang/prometheus"
	"io"
	"net/http"
	"time"
)

func main() {
	metrics := httpclient.NewMetrics("foo", "bar")
	prometheus.DefaultRegisterer.MustRegister(metrics)

	table := []httpclient.CacheTableEntry{
		{
			Endpoint: "/foo/.+",
			IsRegExp: true,
			Expiry:   5 * time.Second,
		},
	}

	c := httpclient.NewCacher(nil, "test", httpclient.Options{PrometheusMetrics: metrics}, table, time.Minute, time.Hour)

	req, _ := http.NewRequest(http.MethodGet, "http://example.com", nil)
	if resp, err := c.Do(req); err == nil {
		body, _ := io.ReadAll(resp.Body)
		fmt.Print(string(body))
		_ = resp.Body.Close()
	}
}
Output:

func NewCacher

func NewCacher(httpClient *http.Client, application string, options Options, cacheEntries []CacheTableEntry, cacheExpiry, cacheCleanup time.Duration) *Cacher

NewCacher creates a new Cacher. It will also use InstrumentedClient to measure API call performance statistics.

func (*Cacher) Do

func (c *Cacher) Do(req *http.Request) (resp *http.Response, err error)

Do sends the request and caches the response for future use. If a (non-expired) cached response exists for the request's URL, it is returned instead.

Note: only the request's URL is used to find a cached version. Currently, it does not consider the request's method (i.e. GET/PUT/etc).

type Caller

type Caller interface {
	Do(req *http.Request) (resp *http.Response, err error)
}

Caller interface of a generic API caller

type InstrumentedClient

type InstrumentedClient struct {
	BaseClient
	Options     Options
	Application string
}

InstrumentedClient implements the Caller interface. If provided by Options, it will collect performance metrics of the API calls and record them for Prometheus to scrape.

Example
package main

import (
	"fmt"
	"github.com/clambin/httpclient"
	"github.com/prometheus/client_golang/prometheus"
	"io"
	"net/http"
)

func main() {
	metrics := httpclient.NewMetrics("foo", "bar")
	prometheus.DefaultRegisterer.MustRegister(metrics)

	c := httpclient.InstrumentedClient{
		Options:     httpclient.Options{PrometheusMetrics: metrics},
		Application: "test",
	}

	req, _ := http.NewRequest(http.MethodGet, "http://example.com", nil)
	if resp, err := c.Do(req); err == nil {
		body, _ := io.ReadAll(resp.Body)
		fmt.Print(string(body))
		_ = resp.Body.Close()
	}
}
Output:

func (*InstrumentedClient) Do

func (c *InstrumentedClient) Do(req *http.Request) (resp *http.Response, err error)

Do sends the request and records performance metrics of the call. Currently, it records the request's duration (i.e. latency) and error rate.

type Metrics

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

Metrics contains Prometheus metrics to capture during API calls. Each metric is expected to have two labels: the first will contain the application issuing the request. The second will contain the endpoint (i.e. Path) of the request.

func NewMetrics

func NewMetrics(namespace, subsystem string) *Metrics

NewMetrics creates a standard set of Prometheus metrics to capture during API calls.

func (*Metrics) Collect added in v0.3.0

func (pm *Metrics) Collect(ch chan<- prometheus.Metric)

Collect implements the prometheus.Collector interface so clients can register Metrics as a whole

func (*Metrics) Describe added in v0.3.0

func (pm *Metrics) Describe(ch chan<- *prometheus.Desc)

Describe implements the prometheus.Collector interface so clients can register Metrics as a whole

type Options

type Options struct {
	PrometheusMetrics *Metrics // Prometheus metric to record API performance metrics
}

Options contains options to alter InstrumentedClient behaviour

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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