hc

package module
v1.0.3 Latest Latest
Warning

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

Go to latest
Published: Jun 17, 2026 License: MIT Imports: 12 Imported by: 0

README

HC (Http Client)

test Go Reference

Simple HTTP Client for Go with interceptor support.

Table of Contents

Installation

go get github.com/morkid/hc

Features

  • Interceptor pattern for request/response customization
  • Request mocking via TakeOver
  • Automatic BaseURL resolution (supports relative paths)
  • Configurable logging (request, response body, headers)
  • Custom logger support
  • Configurable timeout
  • Configurable TLS certificate verification
  • Automatic retry with configurable delay and condition
  • JSON response helper
  • Resty integration

Usage

Basic with Interceptor
import "github.com/morkid/hc"

client := hc.New(hc.Config{
    BaseURL: "http://example.com",
    LogEnabled: true,
    Interceptor: func(req *http.Request) error {
        req.Header.Add("Accept", "application/json")

        // forward to the original request
        return nil
    },
})

req, _ := http.NewRequest("GET", "/hello-world.json", nil)
res, err := client.Do(req)
log.Println(err)
log.Println(res.StatusCode)
BaseURL

Set a BaseURL and use relative paths in your requests. HC will resolve the full URL automatically.

client := hc.New(hc.Config{
    BaseURL: "https://dummyjson.com:443/",
})

req, _ := http.NewRequest("GET", "/products", nil)
res, _ := client.Do(req)
Mocking Response (TakeOver)

The interceptor has two modes:

  1. Return an error — the request is rejected with that error.
  2. Return an *hc.Interceptor with empty ErrorMessage and a TakeOver function — the request is intercepted and the TakeOver function provides a mock response.
helloWorld := hc.Interceptor{
    TakeOver: func(req *http.Request) (res *http.Response, err error) {
        return &http.Response{
            Body:       io.NopCloser(strings.NewReader(`{"message":"hello world"}`)),
            Status:     "200 OK",
            StatusCode: 200,
            Proto:      "HTTP/1.1",
        }, nil
    },
}

client := hc.New(hc.Config{
    Interceptor: func(req *http.Request) error {
        if req.URL.Path == "/hello-world.json" {
            return &helloWorld
        }
        return nil
    },
})

req, _ := http.NewRequest("GET", "/hello-world.json", nil)
res, _ := client.Do(req)
Retry

Retry on failure (error or status >= 500) with a configurable delay.

client := hc.New(hc.Config{
    MaxRetries: 3,
    RetryDelay: time.Second,
})

You can also provide a custom retry condition to control when retries happen:

client := hc.New(hc.Config{
    MaxRetries:     3,
    RetryDelay:     500 * time.Millisecond,
    RetryCondition: func(res *http.Response, err error) bool {
        return err != nil || res.StatusCode >= 500
    },
})

Default is 0 (no retry).

JSON Response Helper

Use hc.JSONResponse to unmarshal the response body directly into a struct.

var result map[string]any
err := hc.JSONResponse(res, &result)

Configuration

Field Type Description
LogEnabled bool Enable request/response logging
LogResponseBodyEnabled bool Enable response body logging
LogHeaderEnabled bool Enable request header logging
LogPrefix string Prefix for log messages
Logger *log.Logger Custom logger instance
Interceptor func(*http.Request) error Intercept and customize requests
Timeout int Timeout in seconds (default: 30)
BaseURL string Base URL for relative path resolution
InsecureSkipVerify bool Skip TLS certificate verification
MaxRetries int Maximum retry attempts (default: 0 = no retry)
RetryDelay time.Duration Delay between retries
RetryCondition func(*http.Response, error) bool Custom retry condition (default: retry on error or status >= 500)

Resty Integration

HC's transport can be dropped into Resty, so you get HC's interceptor, logging, and base URL features through Resty's fluent API.

client := hc.New()

restyClient := resty.New()
restyClient.SetTransport(client.Transport)

res, err := restyClient.R().
    SetHeader("Accept", "application/json").
    Get("http://example.com/hello-world.json")

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func JSONResponse added in v1.0.2

func JSONResponse(res *http.Response, obj any) error

JSONResponse unmarshal response body to json

func New

func New(configs ...Config) *http.Client

New create new http client

Types

type Config

type Config struct {
	LogEnabled             bool                                     // Enable log
	LogResponseBodyEnabled bool                                     // Enable log for response body
	LogHeaderEnabled       bool                                     // Enable header logging
	LogPrefix              string                                   // Log Prefix
	Logger                 *log.Logger                              // Logger instance
	Interceptor            func(req *http.Request) error            // Intercept request
	Timeout                int                                      // Timeout seconds
	BaseURL                string                                   // Base URL
	InsecureSkipVerify     bool                                     // Skip TLS certificate verification (not recommended for production)
	MaxRetries             int                                      // Maximum number of retry attempts (default: 0 = no retry)
	RetryDelay             time.Duration                            // Delay between retries
	RetryCondition         func(res *http.Response, err error) bool // Custom retry condition (default: retry on error or status >= 500)
}

Config http client config

type Interceptor

type Interceptor struct {
	ErrorMessage string
	TakeOver     func(req *http.Request) (res *http.Response, err error)
}

Interceptor is an error that can be used to intercept a request

func (*Interceptor) Error

func (h *Interceptor) Error() string

Error returns the error message

Jump to

Keyboard shortcuts

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