gohttpclient

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

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

Go to latest
Published: Jul 25, 2024 License: MIT Imports: 12 Imported by: 1

README

GoHTTPClient

Go Report Card GoDoc

gohttpclient is a powerful and flexible HTTP client library for Go, designed to enhance and extend the functionality of the standard net/http client. It provides a robust set of features including interceptors, rate limiting, automatic retries, and detailed metrics tracking, making it ideal for building resilient and observable network applications.

Table of Contents

Features

  • Enhanced HTTP Methods: Support for GET, POST, PUT, PATCH, DELETE with easy-to-use interfaces.
  • Request/Response Interceptors: Modify requests before sending and responses after receiving.
  • Rate Limiting: Control request rates to prevent overwhelming servers.
  • Automatic Retries: Configurable retry mechanisms with various backoff strategies.
  • Metrics Tracking: Monitor request counts, error rates, and latencies.
  • Customizable Transport: Fine-tune connection pooling, timeouts, and more.
  • Logging: Built-in logging support with customizable logger interface.
  • Proxy Support: Easy configuration of HTTP and HTTPS proxies.

Installation

To install gohttpclient, use go get:

go get github.com/simp-lee/gohttpclient

Quick Start

Here's a simple example to get you started:

package main

import (
	"context"
	"fmt"
	"github.com/simp-lee/gohttpclient"
)

func main() {
	client := gohttpclient.NewClient()

	resp, err := client.Get(context.Background(), "https://api.example.com/data")
	if err != nil {
		fmt.Println("Error:", err)
		return
	}

	fmt.Println("Response:", string(resp))
}

Advanced Usage

Client Customization

Customize the client behavior using various options:

client := gohttpclient.NewClient(
	gohttpclient.WithTimeout(10 * time.Second),
	gohttpclient.WithRetryTimes(3),
	gohttpclient.WithRateLimit(10, 5),
	gohttpclient.WithMaxIdleConns(100),
	gohttpclient.WithMaxConnsPerHost(10),
)
Interceptors

Add request and response interceptors:

client.AddRequestInterceptor(func(req *http.Request) error {
	req.Header.Set("Authorization", "Bearer token")
	return nil
})

client.AddResponseInterceptor(func(resp *http.Response) error {
	fmt.Println("Response status:", resp.Status)
	return nil
})
Retry Mechanisms

gohttpclient uses the github.com/simp-lee/retry library to implement flexible retry mechanisms. You can configure various backoff strategies to suit your needs:

client := gohttpclient.NewClient(
	gohttpclient.WithRetryTimes(3),
	gohttpclient.WithRetryExponentialBackoff(1*time.Second, 30*time.Second, 100*time.Millisecond),
)

Supported backoff strategies include:

  • Linear Backoff: Increases the delay between retries linearly.
gohttpclient.WithRetryLinearBackoff(2 * time.Second)
  • Constant Backoff: Uses a fixed delay between retries.
gohttpclient.WithRetryConstantBackoff(5 * time.Second)
  • Exponential Backoff with Jitter: Increases the delay exponentially and adds random jitter to prevent thundering herd problems.
gohttpclient.WithRetryExponentialBackoff(1*time.Second, 30*time.Second, 100*time.Millisecond)
  • Random Interval Backoff: Uses a random delay between a minimum and maximum duration.
gohttpclient.WithRetryRandomIntervalBackoff(1*time.Second, 5*time.Second)
  • Custom Backoff Strategy: Implement your own backoff strategy. Refer to the github.com/simp-lee/retry documentation for details.
gohttpclient.WithRetryCustomBackoff(myCustomBackoffFunc)
Metrics Tracking

Retrieve client metrics:

metrics := client.GetMetrics()
fmt.Printf("Requests: %d, Errors: %d, Total Latency: %v\n", 
	metrics.RequestCount, metrics.ErrorCount, 
	time.Duration(metrics.TotalLatency))
Custom Logging

Implement custom logging:

type customLogger struct{}

func (l *customLogger) Info(msg string, keyVals ...interface{})  { /* implementation */ }
func (l *customLogger) Error(msg string, keyVals ...interface{}) { /* implementation */ }
func (l *customLogger) Warn(msg string, keyVals ...interface{})  { /* implementation */ }

client := gohttpclient.NewClient(gohttpclient.WithLogger(&customLogger{}))

Best Practices

  1. Always use context for proper cancellation and timeout handling.
  2. Implement circuit breaking for resilience against failing dependencies.
  3. Use interceptors for cross-cutting concerns like authentication or logging.
  4. Monitor and analyze metrics to optimize client performance.
  5. Configure appropriate timeouts and retry mechanisms for your use case.

API Reference

Client Creation
  • NewClient(options ...ClientOption) *Client Creates a new GoHTTPClient with the specified options.
HTTP Methods
  • Get(ctx context.Context, url string) ([]byte, error)
  • Post(ctx context.Context, url string, body interface{}) ([]byte, error)
  • Put(ctx context.Context, url string, body interface{}) ([]byte, error)
  • Patch(ctx context.Context, url string, body interface{}) ([]byte, error)
  • Delete(ctx context.Context, url string) ([]byte, error)
Client Options
  • WithTimeout(timeout time.Duration) ClientOption
  • WithRateLimit(rps float64, burst int) ClientOption
  • WithLogger(logger Logger) ClientOption
  • WithMaxIdleConns(n int) ClientOption
  • WithMaxConnsPerHost(n int) ClientOption
  • WithIdleConnTimeout(d time.Duration) ClientOption
  • WithTLSHandshakeTimeout(d time.Duration) ClientOption
  • WithDisableKeepAlives(disable bool) ClientOption
  • WithDisableCompression(disable bool) ClientOption
  • WithProxy(proxyURL *url.URL) ClientOption
  • WithCustomTransport(transport *http.Transport) ClientOption
  • WithLogInfoEnabled(enabled bool) ClientOption
Retry Options
  • WithRetryTimes(maxRetries int) ClientOption
  • WithRetryLinearBackoff(interval time.Duration) ClientOption
  • WithRetryConstantBackoff(interval time.Duration) ClientOption
  • WithRetryExponentialBackoff(initialInterval, maxInterval, maxJitter time.Duration) ClientOption
  • WithRetryRandomIntervalBackoff(minInterval, maxInterval time.Duration) ClientOption
  • WithRetryCustomBackoff(backoff retry.Backoff) ClientOption
Interceptors
  • AddRequestInterceptor(interceptor RequestInterceptor)
  • AddResponseInterceptor(interceptor ResponseInterceptor)
Metric
  • GetMetrics() Metrics
Other Methods
  • SetHeader(key, value string)
  • Close()

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

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

Client represents a custom HTTP client with various optimizations

func NewClient

func NewClient(options ...ClientOption) *Client

NewClient creates a new Client with the given options

func (*Client) AddRequestInterceptor

func (c *Client) AddRequestInterceptor(interceptor RequestInterceptor)

AddRequestInterceptor adds a request interceptor

func (*Client) AddResponseInterceptor

func (c *Client) AddResponseInterceptor(interceptor ResponseInterceptor)

AddResponseInterceptor adds a response interceptor

func (*Client) Close

func (c *Client) Close()

Close cancels the base context and closes any idle connections

func (*Client) Delete

func (c *Client) Delete(ctx context.Context, url string) ([]byte, error)

func (*Client) Get

func (c *Client) Get(ctx context.Context, url string) ([]byte, error)

Get sends a GET request

func (*Client) GetMetrics

func (c *Client) GetMetrics() Metrics

GetMetrics returns the current metrics

func (*Client) Patch

func (c *Client) Patch(ctx context.Context, url string, body interface{}) ([]byte, error)

func (*Client) Post

func (c *Client) Post(ctx context.Context, url string, body interface{}) ([]byte, error)

func (*Client) Put

func (c *Client) Put(ctx context.Context, url string, body interface{}) ([]byte, error)

func (*Client) Request

func (c *Client) Request(ctx context.Context, method, url string, body interface{}) ([]byte, error)

Request makes an HTTP request with the given method, URL, and body. It applies all request and response interceptors, and handles retries according to the client's retry options.

func (*Client) SetHeader

func (c *Client) SetHeader(key, value string)

SetHeader sets a header for all requests

type ClientError

type ClientError struct {
	Op   string // operation that failed
	Err  error  // underlying error
	Code int    // HTTP status code, if applicable
}

ClientError represents all possible errors returned by the client

func (*ClientError) Error

func (e *ClientError) Error() string

type ClientOption

type ClientOption func(client *Client)

ClientOption is a function type for client configuration

func WithCustomTransport

func WithCustomTransport(transport *http.Transport) ClientOption

WithCustomTransport sets custom transport for the client

func WithDisableCompression

func WithDisableCompression(disable bool) ClientOption

WithDisableCompression disables automatic decompression of the response body This can be useful if you want to handle decompression yourself

func WithDisableKeepAlives

func WithDisableKeepAlives(disable bool) ClientOption

WithDisableKeepAlives disables HTTP keep-alives This can be useful if you're dealing with servers that don't support keep-alives well

func WithIdleConnTimeout

func WithIdleConnTimeout(d time.Duration) ClientOption

WithIdleConnTimeout sets the maximum amount of time an idle connection will remain idle before closing itself Lower values can help manage resource usage, but may increase latency for new requests

func WithLogInfoEnabled

func WithLogInfoEnabled(enabled bool) ClientOption

WithLogInfoEnabled sets whether Info logging is enabled for the client

func WithLogger

func WithLogger(logger Logger) ClientOption

WithLogger sets a custom logger

func WithMaxConnsPerHost

func WithMaxConnsPerHost(n int) ClientOption

WithMaxConnsPerHost sets the maximum number of connections per host This can prevent a single host from using too many resources

func WithMaxIdleConns

func WithMaxIdleConns(n int) ClientOption

WithMaxIdleConns sets the maximum number of idle connections Increasing this can improve performance for concurrent requests to many hosts

func WithProxy

func WithProxy(proxyURL *url.URL) ClientOption

WithProxy sets a proxy for the client If proxyURL set nil, no proxy will be used, even if the environment variables are set

func WithRateLimit

func WithRateLimit(rps float64, burst int) ClientOption

WithRateLimit sets rate limiting for requests rps is the maximum number of requests per second burst is the maximum number of requests that can be sent at once

func WithRetryConstantBackoff

func WithRetryConstantBackoff(interval time.Duration) ClientOption

WithRetryConstantBackoff sets a constant backoff strategy for retries

func WithRetryCustomBackoff

func WithRetryCustomBackoff(backoff retry.Backoff) ClientOption

WithRetryCustomBackoff sets a custom backoff strategy for retries

func WithRetryExponentialBackoff

func WithRetryExponentialBackoff(initialInterval, maxInterval, maxJitter time.Duration) ClientOption

WithRetryExponentialBackoff sets an exponential backoff strategy with jitter for retries

func WithRetryLinearBackoff

func WithRetryLinearBackoff(interval time.Duration) ClientOption

WithRetryLinearBackoff sets a linear backoff strategy for retries

func WithRetryRandomIntervalBackoff

func WithRetryRandomIntervalBackoff(minInterval, maxInterval time.Duration) ClientOption

WithRetryRandomIntervalBackoff sets a random interval backoff strategy for retries

func WithRetryTimes

func WithRetryTimes(maxRetries int) ClientOption

WithRetryTimes sets the number of retries for failed requests.

func WithTLSHandshakeTimeout

func WithTLSHandshakeTimeout(d time.Duration) ClientOption

WithTLSHandshakeTimeout sets the maximum amount of time waiting for a TLS handshake Increase this if you're dealing with slow or unreliable networks

func WithTimeout

func WithTimeout(timeout time.Duration) ClientOption

WithTimeout sets the overall timeout for requests This includes connection time, any redirects, and reading the response body

type Logger

type Logger interface {
	Info(msg string, keyVals ...interface{})
	Error(msg string, keyVals ...interface{})
	Warn(msg string, keyVals ...interface{})
}

Logger is a simple interface for logging messages

type Metrics

type Metrics struct {
	TotalLatency int64 // in nanoseconds
	RequestCount int64
	ErrorCount   int64
}

Metrics holds metrics for the client

type RequestInterceptor

type RequestInterceptor func(*http.Request) error

RequestInterceptor is a function that can modify requests before they are sent

type ResponseInterceptor

type ResponseInterceptor func(*http.Response) error

ResponseInterceptor is a function that can modify responses after they are received

Jump to

Keyboard shortcuts

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