ghttp

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

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

Go to latest
Published: Dec 13, 2024 License: MIT Imports: 24 Imported by: 2

README

ghttp

A Go HTTP client designed for quick integration with REST APIs.

Installation

go get github.com/nexuer/ghttp

Usage

Options
Configure the HTTP roundTripper

WithTransport(trans http.RoundTripper)

// Example: Configure proxy and client certificates
ghttp.WithTransport(&http.Transport{
    Proxy: ghttp.ProxyURL(":7890"), // or http.ProxyFromEnvironment
    TLSClientConfig: &tls.Config{
        InsecureSkipVerify: true,
    },
}),
Set Default Timeout

WithTimeout(d time.Duration)

// Example: Set a specific timeout
ctx, cancel := context.WithTimeout(context.Background(), 10 * time.Second)
defer cancel()
_, err := client.Invoke(ctx, http.MethodGet, "/api/v4/projects", nil, nil)
Set Default User-Agent

WithUserAgent(userAgent string)

Set Default Endpoint

WithEndpoint(endpoint string)

Set Default Content-Type

WithContentType(contentType string)

Configure Proxy

Default: http.ProxyFromEnvironment, can use ghttp.ProxyURL(url)

WithProxy(f func(*http.Request) (*url.URL, error))

Bind Struct for Non-2xx Status Codes

WithNot2xxError(f func() error)

Enable Debugging

WithDebug(open bool)

Set Limiter

WithLimiter(l Limiter)

Invocation Methods
  • Invoke(ctx context.Context, method, path string, args any, reply any, opts ...CallOption) (*http.Response, error)
  • Do(req *http.Request, opts ...CallOption) (*http.Response, error)

CallOption is an interface that allows customization through method implementation:

type CallOption interface {
    Before(request *http.Request) error
    After(response *http.Response) error
}
Binding
Request Query

usage

Encoding

Automatically loads the corresponding Codec instance based on content-type. Subtype extraction occurs (e.g., both application/json and application/vnd.api+json are treated as json).

Custom Codec Override default JSON serialization using sonic:

package main

import (
    "github.com/bytedance/sonic"
    "github.com/nexuer/ghttp"
)

type codec struct{}

func (codec) Name() string {
    return "sonic-json"
}

func (codec) Marshal(v interface{}) ([]byte, error) {
    return sonic.Marshal(v)
}

func (codec) Unmarshal(data []byte, v interface{}) error {
    return sonic.Unmarshal(data, v)
}

func main() {
    ghttp.RegisterCodec("application/json", codec{})
}
Debugging

Enable debugging with WithDebug, output example:

--------------------------------------------
Trace                         Value                          
--------------------------------------------
DNSDuration                   3.955292ms                    
ConnectDuration               102.718541ms                  
TLSHandshakeDuration          98.159333ms                   
RequestDuration               138.834µs                     
WaitResponseDuration          307.559875ms                  
TotalDuration                 412.40375ms                   

* Host gitlab.com:443 was resolved.
* IPv4: 198.18.7.159
*   Trying 198.18.7.159:443...
* Connected to gitlab.com (198.18.7.159) port 443
* SSL connection using TLS 1.3 / TLS_AES_128_GCM_SHA256
* ALPN: server accepted h2
* using HTTP/1.1
> POST /oauth/token HTTP/1.1
> User-Agent: sdk/gitlab-v0.0.1
> Accept: application/json
> Content-Type: application/json
> Beforehook: BeforeHook
> Authorization: Basic Z2l0bGFiOnBhc3N3b3Jk
>

{
    "client_id": "app",
    "grant_type": "password"
}

> HTTP/2.0 401 Unauthorized
... (remaining output truncated for brevity)

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BindResponseBody

func BindResponseBody(response *http.Response, reply any) error

func CodecForRequest

func CodecForRequest(r *http.Request, name ...string) (encoding.Codec, bool)

CodecForRequest get encoding.Codec via http.Request

func CodecForResponse

func CodecForResponse(r *http.Response, name ...string) (encoding.Codec, bool)

CodecForResponse get encoding.Codec via http.Response

func CodecForString

func CodecForString(contentType string) encoding.Codec

CodecForString get encoding.Codec via string

func ForceHttps

func ForceHttps(endpoint string) string

func IsTimeout

func IsTimeout(err error) bool

func Not2xxCode

func Not2xxCode(code int) bool

func ProxyURL

func ProxyURL(address string) func(*http.Request) (*url.URL, error)

func RegisterCodec

func RegisterCodec(contentType string, codec encoding.Codec)

func RegisterCodecName

func RegisterCodecName(contentType string, name string)

func SetClient

func SetClient(c *Client)

func SetQuery

func SetQuery(req *http.Request, q any) error

func SetRequestBody

func SetRequestBody(req *http.Request, body io.Reader) error

func StatusForErr

func StatusForErr(err error) (int, bool)

Types

type CallOption

type CallOption interface {
	Before(request *http.Request) error
	After(response *http.Response) error
}

func After

func After(hooks ...ResponseFunc) CallOption

func BasicAuth

func BasicAuth(username, password string) CallOption

func BearerToken

func BearerToken(token string) CallOption

func Before

func Before(hooks ...RequestFunc) CallOption

func Query

func Query(q any) CallOption

type CallOptions

type CallOptions struct {
	// Set query parameters
	Query any

	// Basic auth
	Username string
	Password string

	// Bearer token
	BearerToken string

	// hooks
	BeforeHooks []RequestFunc
	AfterHooks  []ResponseFunc
}

CallOptions default call options

func (*CallOptions) After

func (c *CallOptions) After(response *http.Response) error

func (*CallOptions) Before

func (c *CallOptions) Before(request *http.Request) error

type Client

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

Client is an HTTP client.

func NewClient

func NewClient(opts ...ClientOption) *Client

func (*Client) Do

func (c *Client) Do(req *http.Request, opts ...CallOption) (*http.Response, error)

Do send an HTTP request and decodes the body of response into target.

func (*Client) Invoke

func (c *Client) Invoke(ctx context.Context, method, path string, args any, reply any, opts ...CallOption) (*http.Response, error)

func (*Client) SetEndpoint

func (c *Client) SetEndpoint(endpoint string)

type ClientOption

type ClientOption func(*clientOptions)

ClientOption is HTTP client option.

func WithContentType

func WithContentType(contentType string) ClientOption

WithContentType with client request content type.

func WithDebug

func WithDebug(open bool) ClientOption

WithDebug open debug.

func WithDebugInterface

func WithDebugInterface(f func() DebugInterface) ClientOption

WithDebugInterface sets the function to create a new DebugInterface instance.

func WithEndpoint

func WithEndpoint(endpoint string) ClientOption

WithEndpoint with client addr.

func WithLimiter

func WithLimiter(l Limiter) ClientOption

WithLimiter sets a rate limiter for the client. This limiter will be applied to control the number of requests made to the server, ensuring that the requests stay within the specified limits.

func WithNot2xxError

func WithNot2xxError(f func() error) ClientOption

WithNot2xxError handle response status code < 200 and code > 299

func WithProxy

func WithProxy(f func(*http.Request) (*url.URL, error)) ClientOption

WithProxy with proxy url.

func WithTLSConfig

func WithTLSConfig(cfg *tls.Config) ClientOption

WithTLSConfig with tls config.

func WithTimeout

func WithTimeout(timeout time.Duration) ClientOption

WithTimeout with client request timeout.

func WithTransport

func WithTransport(transport http.RoundTripper) ClientOption

WithTransport with http.RoundTrippe.

func WithUserAgent

func WithUserAgent(userAgent string) ClientOption

WithUserAgent with client user agent.

type Debug

type Debug struct {
	Writer        io.Writer
	Trace         bool
	TraceCallback func(w io.Writer, info TraceInfo)
	// contains filtered or unexported fields
}

func (*Debug) After

func (d *Debug) After(request *http.Request, response *http.Response, err error)

func (*Debug) Before

func (d *Debug) Before(req *http.Request)

type DebugInterface

type DebugInterface interface {
	Before(request *http.Request)
	After(request *http.Request, response *http.Response, err error)
}

type Error

type Error struct {
	URL        *url.URL
	Method     string
	StatusCode int
	Err        error
}

func (Error) Error

func (e Error) Error() string

func (Error) Unwrap

func (e Error) Unwrap() error

type Limiter

type Limiter interface {
	Wait(ctx context.Context) error
}

type RequestFunc

type RequestFunc func(request *http.Request) error

type ResponseFunc

type ResponseFunc func(response *http.Response) error

type TraceInfo

type TraceInfo struct {
	DNSDuration          time.Duration `json:"DNSDuration,omitempty" yaml:"DNSDuration" xml:"DNSDuration"`
	ConnectDuration      time.Duration `json:"connectDuration,omitempty" yaml:"connectDuration" xml:"connectDuration"`
	TLSHandshakeDuration time.Duration `json:"TLSHandshakeDuration,omitempty" yaml:"TLSHandshakeDuration" xml:"TLSHandshakeDuration"`
	RequestDuration      time.Duration `json:"requestDuration,omitempty" yaml:"requestDuration" xml:"requestDuration"`
	WaitResponseDuration time.Duration `json:"waitResponseDuration,omitempty" yaml:"waitResponseDuration" xml:"waitResponseDuration"`
	ResponseDuration     time.Duration `json:"responseDuration,omitempty" yaml:"responseDuration" xml:"responseDuration"`
	TotalDuration        time.Duration `json:"totalDuration,omitempty" yaml:"totalDuration" xml:"totalDuration"`
	// contains filtered or unexported fields
}

func (TraceInfo) Context

func (t TraceInfo) Context() context.Context

func (TraceInfo) String

func (t TraceInfo) String() string

func (TraceInfo) Table

func (t TraceInfo) Table() []byte

Directories

Path Synopsis
xml

Jump to

Keyboard shortcuts

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