httpz

package module
v0.5.1 Latest Latest
Warning

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

Go to latest
Published: Aug 12, 2025 License: MIT Imports: 16 Imported by: 0

README

HTTPZ - HTTP client

httpz simplify the process of making HTTP requests. It a wrapper around resty.dev/v3, with built-in request/response logging and opentelemetry tracing middleware. It also support retry mechanism and circuit breaker pattern.

Features

  • Configurable
  • Typed response result
  • Structured logging middleware
  • OpenTelemetry tracing middleware
  • Retry mechanism
  • Circuit breaker

Installation

go get github.com/unlimited-budget-ecommerce/httpz

Usage

Initializing httpz
// paths should comes from config.yaml file
// this is just an example.
paths := map[string]string{
	"createUser": "/users",
	"getUser":    "/users/{id}",
}

client := httpz.NewClient(
	"service-name",                         // set to "User-Agent"
	"https://api.example.com",              // base url
	httpz.WithTransport(&http.Transport{}), // default: [http.DefaultTransport]
	httpz.WithBaseHeaders(nil),             // default: nil (type map[string]string)
	httpz.WithPaths(paths),                 // default: map[string]string{}
	httpz.WithLogger(slog.Default()),       // default: [slog.Default]
	httpz.WithLogMWEnabled(true),           // request/response logging, default: false
	httpz.WithTracer(nil),                  // default: [otel.GetTracerProvider]
	httpz.WithPropagator(nil),              // default: [otel.GetTextMapPropagator]
	httpz.WithOtelMWEnabled(true),          // opentelemetry tracing, default: false
	httpz.WithServiceVersion(""),           // set to "User-Agent", default: ""
	// read function doc for more details
	httpz.WithCircuitBreaker(0, 0, 0, nil), // passing zero values will result to default values: 10s, 3, 1, Status Code 500 and above
	httpz.WithCircuitBreakerEnabled(true),  // default: false
)
Making a POST request
// expected result struct when making a request
result := &CreateUserRes{}

res, err := client.NewRequest(context.Background()).
	SetBody(&CreateUserReq{}). // example request body
	SetResult(result).
	Post(client.GetPath("createUser"))
if err != nil {
	return nil, fmt.Errorf("failed to create user: %w", err)
}
if res.IsError() {
	return res, fmt.Errorf("error creating user, got status: %d" ,res.StatusCode())
}
Making a GET request
// expected result struct when making a request
result := &GetUserRes{}

res, err := client.NewRequest(context.Background()).
	SetPathParams(map[string]string{"id": "1"}).
	SetQueryParams(map[string]string{"foo": "bar"}).
	SetResult(result).
	Get(client.GetPath("getUser"))

// handle error
Making a request with retries

You can configure retry attempts, wait times, and conditions for retrying a request. Default retry strategy is exponential backoff with a jitter

To enable and configure retries, you would typically interact with the Client or Request struct. Reference: https://resty.dev/docs/retry-mechanism/

client :=  httpz.NewClient("", "")
client.
	SetAllowNonIdempotentRetry(true).         // default: false (enable retry for POST request)
	SetRetryCount(1).                         // default: 0 (total attempt = initial attempt + retry count)
	SetRetryWaitTime(100 * time.Millisecond). // default: 100ms
	SetRetryMaxWaitTime(2 * time.Second)      // default: 2s

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func WithBaseHeaders added in v0.2.0

func WithBaseHeaders(h map[string]string) option

func WithCircuitBreaker added in v0.4.0

func WithCircuitBreaker(
	timeout time.Duration,
	failureThreshold, successThreshold uint32,
	policies ...func(*http.Response) bool,
) option

WithCircuitBreaker accepts:

  • timeout - duration window for circuit breaker to determine the state
  • failureThreshold - number of failures that must occur within the timeout duration to transition to Open state
  • successThreshold - number of successes that must occur to transition from Half-Open state to Closed state
  • policies - determine whether a request is failed or successful by evaluating the response instance

passing zero values will result to default values: 10s, 3, 1, Status Code 500 and above

func WithCircuitBreakerEnabled added in v0.4.0

func WithCircuitBreakerEnabled(enabled bool) option

func WithLogMWEnabled

func WithLogMWEnabled(enabled bool) option

func WithLogger

func WithLogger(l *slog.Logger) option

func WithOtelMWEnabled

func WithOtelMWEnabled(enabled bool) option

func WithPaths

func WithPaths(p map[string]string) option

func WithPropagator

func WithPropagator(p propagation.TextMapPropagator) option

func WithServiceVersion added in v0.1.1

func WithServiceVersion(version string) option

func WithTracer

func WithTracer(t trace.TracerProvider) option

func WithTransport

func WithTransport(t *http.Transport) option

Types

type Client added in v0.1.2

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

func NewClient added in v0.2.0

func NewClient(clientName, baseURL string, opts ...option) *Client

func (*Client) GetPath added in v0.5.0

func (c *Client) GetPath(pathName string) string

func (*Client) NewRequest added in v0.5.0

func (c *Client) NewRequest(ctx context.Context) *resty.Request

NewRequest returns *resty.Request from given context.

It sets default headers "Content-Type" to "application/json" and "User-Agent" based on the client name and version.

Jump to

Keyboard shortcuts

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