easyhttp

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Oct 20, 2025 License: MIT Imports: 8 Imported by: 0

README

go-easyhttp

Lightweight, ergonomic HTTP client for Go, with sane defaults, connection pooling, per-host limits, and timeouts. JSON is powered by bytedance/sonic for high performance.

English | 中文文档

Features

  • Chainable request builder (GET/POST/PUT/DELETE)
  • Per-host connection limits and timeouts
  • Fast JSON marshal/unmarshal with sonic
  • Simple, minimal API surface
  • Pluggable options (custom http.Client/Transport, timeouts, conn limits)

Install

go get github.com/lockp111/go-easyhttp

Quick start

package main

import (
    "context"
    "fmt"
    "time"

    easyhttp "github.com/lockp111/go-easyhttp"
)

type Resp struct {
    Message string `json:"message"`
}

func main() {
    client := easyhttp.NewClient(
        easyhttp.Config{
            MaxConns:        100,
            Timeout:         5 * time.Second,
            ResponseTimeout: 4 * time.Second,
            ConnTimeout:     1 * time.Second,
            IdleConnTimeout: 90 * time.Second,
        },
        // Options are optional and can override parts of the config at runtime
        easyhttp.WithTimeout(10*time.Second),
        easyhttp.WithMaxConns(200),
    )

    req, _ := easyhttp.NewGet("https://httpbin.org/get")
    req.AddHeader("Accept", "application/json").AddQuery("q", "ping")

    resp, err := client.Fetch(context.Background(), req)
    if err != nil { panic(err) }

    var data map[string]any
    if err := resp.Unmarshal(&data); err != nil { panic(err) }
    fmt.Println("status:", resp.Status, "args:", data["args"])
}

JSON request body

payload := map[string]any{"name": "alice"}
req, _ := easyhttp.NewPost("https://httpbin.org/post")
_, _ = req.SetJSON(payload) // sets Content-Type and body

Streaming request body

// Stream from an io.Reader without buffering into memory
file, _ := os.Open("bigfile.bin")
defer file.Close()

req, _ := easyhttp.NewPost("https://httpbin.org/post")
req.SetHeader("Content-Type", "application/octet-stream")
req.SetBodyReader(file)

Configuration

cfg := easyhttp.Config{
    MaxConns:        1000,            // per-host limits
    Timeout:         30 * time.Second, // >= ResponseTimeout + ConnTimeout
    ResponseTimeout: 10 * time.Second,
    ConnTimeout:     2 * time.Second,
    IdleConnTimeout: 90 * time.Second,
    DisableHttp2:    false,
}
client := easyhttp.NewClient(cfg)

API overview

  • type Client
    • Fetch(ctx, *Request) (*Response, error)
    • Options: WithHTTPClient, WithTransport, WithTimeout, WithMaxConns, WithConnTimeout, WithResponseHeaderTimeout, WithIdleConnTimeout, WithDisableHTTP2
  • type Request
    • Constructors: NewRequest, NewGet, NewPost, NewPut, NewDelete, NewPatch, NewHead, NewOptions, NewConnect, NewTrace
    • Builders: SetPath, AddHeader, SetHeader, DelHeader, AddQuery, SetQuery, DelQuery, SetBody, SetJSON, SetBodyReader
    • Getters: GetUrl, GetMethod, GetHeader, GetBody, etc.
  • type Response
    • GetBodyBytes, GetBodyString, Unmarshal

License MIT

Further reading

  • Best practices: docs/best-practices.md
  • Examples: see the examples/ directory. Each example is an isolated Go module with its own go.mod (using replace), so the root go.mod remains untouched.

Documentation

Index

Constants

View Source
const (
	MethodGet     = http.MethodGet
	MethodPost    = http.MethodPost
	MethodPut     = http.MethodPut
	MethodDelete  = http.MethodDelete
	MethodPatch   = http.MethodPatch
	MethodHead    = http.MethodHead
	MethodOptions = http.MethodOptions
	MethodConnect = http.MethodConnect
	MethodTrace   = http.MethodTrace
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

type Client struct {
	Conf Config
	// contains filtered or unexported fields
}

func NewClient

func NewClient(cfg Config, opts ...Option) *Client

func (*Client) Fetch

func (r *Client) Fetch(ctx context.Context, req *Request) (*Response, error)

type Config

type Config struct {
	MaxConns        int           // Maximum concurrent connections per host
	Timeout         time.Duration // Total timeout, Timeout >= ResponseTimeout + ConnTimeout
	ResponseTimeout time.Duration // Response header timeout
	ConnTimeout     time.Duration // Connection timeout
	IdleConnTimeout time.Duration // Idle connection timeout
	DisableHttp2    bool          // Disable HTTP/2 when true
}

type Option

type Option func(*Client)

func WithConnTimeout

func WithConnTimeout(d time.Duration) Option

WithConnTimeout sets TCP connect timeout and TLS handshake timeout

func WithDisableHTTP2

func WithDisableHTTP2(disable bool) Option

WithDisableHTTP2 disables HTTP/2 when set to true

func WithHTTPClient

func WithHTTPClient(hc *http.Client) Option

WithHTTPClient overrides the underlying http.Client

func WithIdleConnTimeout

func WithIdleConnTimeout(d time.Duration) Option

WithIdleConnTimeout sets idle connection timeout

func WithMaxConns

func WithMaxConns(n int) Option

WithMaxConns sets per-host connection limits

func WithResponseHeaderTimeout

func WithResponseHeaderTimeout(d time.Duration) Option

WithResponseHeaderTimeout sets response header timeout

func WithTimeout

func WithTimeout(d time.Duration) Option

WithTimeout sets the overall client timeout

func WithTransport

func WithTransport(tr http.RoundTripper) Option

WithTransport overrides the transport on the underlying http.Client

type Request

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

func NewConnect

func NewConnect(baseUrl string) (*Request, error)

func NewDelete

func NewDelete(baseUrl string) (*Request, error)

func NewGet

func NewGet(baseUrl string) (*Request, error)

func NewHead

func NewHead(baseUrl string) (*Request, error)

func NewOptions

func NewOptions(baseUrl string) (*Request, error)

func NewPatch

func NewPatch(baseUrl string) (*Request, error)

func NewPost

func NewPost(baseUrl string) (*Request, error)

func NewPut

func NewPut(baseUrl string) (*Request, error)

func NewRequest

func NewRequest(method, baseUrl string) (*Request, error)

func NewTrace

func NewTrace(baseUrl string) (*Request, error)

func (*Request) AddHeader

func (r *Request) AddHeader(key, value string) *Request

func (*Request) AddQuery

func (r *Request) AddQuery(key, value string) *Request

func (*Request) DelHeader

func (r *Request) DelHeader(key string) *Request

func (*Request) DelQuery

func (r *Request) DelQuery(key string) *Request

func (*Request) GetBaseUrl

func (r *Request) GetBaseUrl() string

func (*Request) GetBody

func (r *Request) GetBody() io.Reader

func (*Request) GetHeader

func (r *Request) GetHeader() http.Header

func (*Request) GetMethod

func (r *Request) GetMethod() string

func (*Request) GetPath

func (r *Request) GetPath() string

func (*Request) GetQuery

func (r *Request) GetQuery() string

func (*Request) GetRawQuery

func (r *Request) GetRawQuery() url.Values

func (*Request) GetUrl

func (r *Request) GetUrl() string

func (*Request) SetBody

func (r *Request) SetBody(body []byte) *Request

func (*Request) SetBodyReader

func (r *Request) SetBodyReader(reader io.Reader) *Request

SetBodyReader allows streaming request body without buffering into memory

func (*Request) SetHeader

func (r *Request) SetHeader(key, value string) *Request

func (*Request) SetJSON

func (r *Request) SetJSON(body any) (*Request, error)

func (*Request) SetPath

func (r *Request) SetPath(path string) *Request

func (*Request) SetQuery

func (r *Request) SetQuery(key, value string) *Request

type Response

type Response struct {
	Status     int
	StatusText string
	Header     http.Header
	// contains filtered or unexported fields
}

func (*Response) GetBodyBytes

func (r *Response) GetBodyBytes() []byte

func (*Response) GetBodyString

func (r *Response) GetBodyString() string

func (*Response) Unmarshal

func (r *Response) Unmarshal(v any) error

Jump to

Keyboard shortcuts

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