chttp

package module
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: May 25, 2024 License: MIT Imports: 9 Imported by: 0

README

cHTTP

Go Reference Build codecov Go Report Card GitHub license

cHTTP is a Golang HTTP client wrapper provided with middleware.

Middleware level is based on the modified http.Client.Transport (http.RoundTripper).

Client

chttp.Client an HTTP client wrapper provided with the full list of unified HTTP methods and global method Do from the basic http.Client.

func (c *Client) GET    (ctx context.Context, url string, body ...[]byte) (*http.Response, error)
func (c *Client) HEAD   (ctx context.Context, url string, body ...[]byte) (*http.Response, error)
func (c *Client) POST   (ctx context.Context, url string, body ...[]byte) (*http.Response, error)
func (c *Client) PUT    (ctx context.Context, url string, body ...[]byte) (*http.Response, error)
func (c *Client) PATCH  (ctx context.Context, url string, body ...[]byte) (*http.Response, error)
func (c *Client) DELETE (ctx context.Context, url string, body ...[]byte) (*http.Response, error)
func (c *Client) CONNECT(ctx context.Context, url string, body ...[]byte) (*http.Response, error)
func (c *Client) OPTIONS(ctx context.Context, url string, body ...[]byte) (*http.Response, error)
func (c *Client) TRACE  (ctx context.Context, url string, body ...[]byte) (*http.Response, error)

All methods have several body arguments as the latest one, but the valid is only the first one, such implementation was done to simplify the interface of the function and calls without a body required.

Usage example:

package main

import (
	"context"
	"fmt"
	"net/http/httputil"
	
	"github.com/spyzhov/chttp"
)

func main() {
	client := chttp.NewClient(nil)
	response, _ := client.HEAD(context.TODO(), "https://go.dev/")
	
	data, _ := httputil.DumpResponse(response, false)
	fmt.Println(string(data))
}
JSON

chttp.JSONClient is a chttp.Client wrapper to simplify the routine of marshaling/unmarshalling structures using JSON in requests. The JSON client takes the responsibility to marshal the request object and unmarshal the response body to a given object structure.

If the request fails, due to (un)marshaling or HTTP request (status code >= 300), the result will be wrapped with the *chttp.Error, which will have the http.Response, its body, and the basic error if it exists.

chttp.JSONClient provided with the full list of unified HTTP methods:

func (c *JSONClient) GET    (ctx context.Context, url string, body interface{}, result interface{}) error
func (c *JSONClient) HEAD   (ctx context.Context, url string, body interface{}, result interface{}) error
func (c *JSONClient) POST   (ctx context.Context, url string, body interface{}, result interface{}) error
func (c *JSONClient) PUT    (ctx context.Context, url string, body interface{}, result interface{}) error
func (c *JSONClient) PATCH  (ctx context.Context, url string, body interface{}, result interface{}) error
func (c *JSONClient) DELETE (ctx context.Context, url string, body interface{}, result interface{}) error
func (c *JSONClient) CONNECT(ctx context.Context, url string, body interface{}, result interface{}) error
func (c *JSONClient) OPTIONS(ctx context.Context, url string, body interface{}, result interface{}) error
func (c *JSONClient) TRACE  (ctx context.Context, url string, body interface{}, result interface{}) error

Usage example:

package main

import (
	"context"
	"fmt"
	
	"github.com/spyzhov/chttp"
)

func main() {
	var fact struct {
		Data []struct {
			Fact string `json:"fact"`
		} `json:"data"`
	}
	client := chttp.NewJSON(nil) // same as chttp.NewClient(nil).JSON()
	_ = client.GET(context.TODO(), "https://catfact.ninja/facts?limit=1&max_length=140", nil, &fact)

	fmt.Println(fact.Data[0].Fact)
}

Middleware

Middlewares are the cHTTPs main driver. Adding various middlewares gives the ability to manage requests, adding tracing, logs, and headers transparently into all requests through the cHTTP clients.

Current interface of the middleware is based on 2 types of functions:

// Middleware is an extended interface to the RoundTrip function of the http.RoundTripper interface.
type Middleware func(request *http.Request, next func(request *http.Request) (*http.Response, error)) (*http.Response, error)

Usage example:

package main

import (
	"context"
	"fmt"
	"net/http"

	"github.com/spyzhov/chttp"
	"github.com/spyzhov/chttp/middleware"
)

func main() {
	var fact struct {
		Data []struct {
			Fact string `json:"fact"`
		} `json:"data"`
	}
	client := chttp.NewJSON(nil)
	client.With(middleware.JSON(), middleware.Debug(true, nil))
	client.With(func(request *http.Request, next func(request *http.Request) (*http.Response, error)) (*http.Response, error) {
		fmt.Println("Before the request")
		resp, err := next(request)
		fmt.Println("After the request")
		return resp, err
	})
	_ = client.GET(context.TODO(), "https://catfact.ninja/facts?limit=1&max_length=140", nil, &fact)

	fmt.Println(fact.Data[0].Fact)
}

Usage example with Option:

package main

import (
	"context"
	"fmt"
	"net/http"

	"github.com/spyzhov/chttp"
	"github.com/spyzhov/chttp/middleware"
)

func main() {
	var fact struct {
		Data []struct {
			Fact string `json:"fact"`
		} `json:"data"`
	}
	client := chttp.NewJSON(nil, chttp.WithMiddleware(
		middleware.JSON(), 
		middleware.Debug(true, nil),
		func(request *http.Request, next func(request *http.Request) (*http.Response, error)) (*http.Response, error) {
			fmt.Println("Before the request")
			resp, err := next(request)
			fmt.Println("After the request")
			return resp, err
		},
    ))
	_ = client.GET(context.TODO(), "https://catfact.ninja/facts?limit=1&max_length=140", nil, &fact)

	fmt.Println(fact.Data[0].Fact)
}
List of middlewares
CustomHeaders

Adds a custom headers based on the request.

Example:

client := chttp.NewClient(nil)
client.With(middleware.CustomHeaders(func(request *http.Request) map[string]string {
    if request.Method == http.MethodPost {
        return map[string]string{
            "Accept": "*/*",
        }
    }
    return nil
}))
Debug

NB! Don't use it in production!

Dumps requests and responses in the logs.

Example:

client := chttp.NewClient(nil)
client.With(middleware.Debug(true, nil))
Headers

Adds a static headers.

Example:

client := chttp.NewClient(nil)
client.With(middleware.Headers(map[string]string{
    "Accept": "*/*",
}))
JSON

Adds a Content-Type and Accept headers with the application/json value.

Example:

client := chttp.NewClient(nil)
client.With(middleware.JSON())
Trace

Adds short logs on each request.

Example:

client := chttp.NewClient(nil)
client.With(middleware.Trace(nil))

License

MIT licensed. See the LICENSE file for details.

Documentation

Overview

Package chttp (cHTTP) is an HTTP client wrapper provided with middleware.

Middleware level is based on the modified http.Client Transport (http.RoundTripper).

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrStatusCode = fmt.Errorf("wrong status code")
	ErrUnknown    = fmt.Errorf("unknown error")
)

Functions

func ErrorUnmarshalTo added in v1.2.0

func ErrorUnmarshalTo[Result any](err error) (result Result, _ error)

Types

type Client

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

Client is an HTTP client wrapper that injects middleware transport in the http.Client and provides a list of useful methods.

func NewClient

func NewClient(client *http.Client, options ...Option) *Client

NewClient is a constructor for the Client. If no http.Client provided as an argument, a new client will be created.

Example
Output:

from middleware -> status: 200

func (*Client) CONNECT

func (c *Client) CONNECT(ctx context.Context, url string, body ...[]byte) (*http.Response, error)

CONNECT is an alias to do the Request with the http.MethodConnect method.

func (*Client) Clone added in v1.2.0

func (c *Client) Clone() *Client

Clone will clone an instance of the Client without references to the old one.

func (*Client) DELETE

func (c *Client) DELETE(ctx context.Context, url string, body ...[]byte) (*http.Response, error)

DELETE is an alias to do the Request with the http.MethodDelete method.

func (*Client) Do

func (c *Client) Do(request *http.Request) (*http.Response, error)

Do is the proxy to the same method in the http.Client.

func (*Client) GET

func (c *Client) GET(ctx context.Context, url string, body ...[]byte) (*http.Response, error)

GET is an alias to do the Request with the http.MethodGet method.

func (*Client) HEAD

func (c *Client) HEAD(ctx context.Context, url string, body ...[]byte) (*http.Response, error)

HEAD is an alias to do the Request with the http.MethodHead method.

func (*Client) JSON

func (c *Client) JSON() *JSONClient

JSON creates a JSONClient wrapper with the given Client as a basic one.

func (*Client) Method

func (c *Client) Method(method string) func(ctx context.Context, url string, body ...[]byte) (*http.Response, error)

Method returns a function implementation of the HTTP Method from the Client by its name. Returns Client.GET as the default method.

func (*Client) OPTIONS

func (c *Client) OPTIONS(ctx context.Context, url string, body ...[]byte) (*http.Response, error)

OPTIONS is an alias to do the Request with the http.MethodOptions method.

func (*Client) PATCH

func (c *Client) PATCH(ctx context.Context, url string, body ...[]byte) (*http.Response, error)

PATCH is an alias to do the Request with the http.MethodPatch method.

func (*Client) POST

func (c *Client) POST(ctx context.Context, url string, body ...[]byte) (*http.Response, error)

POST is an alias to do the Request with the http.MethodPost method.

func (*Client) PUT

func (c *Client) PUT(ctx context.Context, url string, body ...[]byte) (*http.Response, error)

PUT is an alias to do the Request with the http.MethodPut method.

func (*Client) Request

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

Request creates a http.Request with the given arguments and calls the Client.Do method.

func (*Client) TRACE

func (c *Client) TRACE(ctx context.Context, url string, body ...[]byte) (*http.Response, error)

TRACE is an alias to do the Request with the http.MethodTrace method.

func (*Client) With

func (c *Client) With(middleware ...Middleware)

With appends Middleware to the end of the list. The first added will be called first (FIFO).

type Error

type Error struct {
	Response *http.Response
	Body     []byte
	Base     error
}

func (*Error) Error

func (e *Error) Error() string

func (*Error) IsStatusCode added in v1.2.0

func (e *Error) IsStatusCode() bool

func (*Error) UnmarshalTo added in v1.2.0

func (e *Error) UnmarshalTo(value interface{}) (bool, error)

func (*Error) Unwrap

func (e *Error) Unwrap() error

type GenericJSONClient added in v1.2.0

type GenericJSONClient[Result any] struct {
	JSONClient
}

GenericJSONClient is an HTTP client wrapper around the Client with automated marshaling of the request body and unmarshaling response body into a known structure.

func NewGenericJSONClient added in v1.2.0

func NewGenericJSONClient[Result any](json *JSONClient) *GenericJSONClient[Result]

NewGenericJSONClient wraps JSONClient with the GenericJSONClient.

Example
Output:

func (*GenericJSONClient[Result]) CONNECT added in v1.2.0

func (c *GenericJSONClient[Result]) CONNECT(ctx context.Context, url string, body interface{}) (Result, error)

CONNECT is an alias to do the Request with the http.MethodConnect method.

func (*GenericJSONClient[Result]) Clone added in v1.2.0

func (c *GenericJSONClient[Result]) Clone() *GenericJSONClient[Result]

Clone will clone an instance of the GenericJSONClient without references to the old one.

func (*GenericJSONClient[Result]) DELETE added in v1.2.0

func (c *GenericJSONClient[Result]) DELETE(ctx context.Context, url string, body interface{}) (Result, error)

DELETE is an alias to do the Request with the http.MethodDelete method.

func (*GenericJSONClient[Result]) GET added in v1.2.0

func (c *GenericJSONClient[Result]) GET(ctx context.Context, url string, body interface{}) (Result, error)

GET is an alias to do the Request with the http.MethodGet method.

func (*GenericJSONClient[Result]) HEAD added in v1.2.0

func (c *GenericJSONClient[Result]) HEAD(ctx context.Context, url string, body interface{}) (Result, error)

HEAD is an alias to do the Request with the http.MethodHead method.

func (*GenericJSONClient[Result]) Method added in v1.2.0

func (c *GenericJSONClient[Result]) Method(
	method string,
) func(ctx context.Context, url string, body interface{}) (Result, error)

Method returns a function implementation of the HTTP Method from the Client by its name. Returns Client.GET as the default method.

func (*GenericJSONClient[Result]) OPTIONS added in v1.2.0

func (c *GenericJSONClient[Result]) OPTIONS(ctx context.Context, url string, body interface{}) (Result, error)

OPTIONS is an alias to do the Request with the http.MethodOptions method.

func (*GenericJSONClient[Result]) PATCH added in v1.2.0

func (c *GenericJSONClient[Result]) PATCH(ctx context.Context, url string, body interface{}) (Result, error)

PATCH is an alias to do the Request with the http.MethodPatch method.

func (*GenericJSONClient[Result]) POST added in v1.2.0

func (c *GenericJSONClient[Result]) POST(ctx context.Context, url string, body interface{}) (Result, error)

POST is an alias to do the Request with the http.MethodPost method.

func (*GenericJSONClient[Result]) PUT added in v1.2.0

func (c *GenericJSONClient[Result]) PUT(ctx context.Context, url string, body interface{}) (Result, error)

PUT is an alias to do the Request with the http.MethodPut method.

func (*GenericJSONClient[Result]) Request added in v1.2.0

func (c *GenericJSONClient[Result]) Request(
	ctx context.Context,
	method string,
	url string,
	body interface{},
) (result Result, err error)

Request prepares the request by marshaling request body and tries to unmarshal response with the JSONClient.UnmarshalHTTPResponse function.

func (*GenericJSONClient[Result]) TRACE added in v1.2.0

func (c *GenericJSONClient[Result]) TRACE(ctx context.Context, url string, body interface{}) (Result, error)

TRACE is an alias to do the Request with the http.MethodTrace method.

func (*GenericJSONClient[Result]) UnmarshalHTTPResponse added in v1.2.0

func (c *GenericJSONClient[Result]) UnmarshalHTTPResponse(
	response *http.Response,
	httpErr error,
) (result Result, err error)

UnmarshalHTTPResponse tries to unmarshal the response body into the given result interface. Result should be reference type and not nil.

type JSONClient

type JSONClient struct {
	*Client
}

JSONClient is an HTTP client wrapper around the Client with automated marshaling of the request body and unmarshaling response body.

func JSON

func JSON(client *Client) *JSONClient

JSON wraps Client with the JSONClient.

func NewJSON

func NewJSON(client *http.Client, options ...Option) *JSONClient

NewJSON creates a JSONClient with new Client based on given http.Client.

func (*JSONClient) CONNECT

func (c *JSONClient) CONNECT(ctx context.Context, url string, body interface{}, result interface{}) error

CONNECT is an alias to do the Request with the http.MethodConnect method.

func (*JSONClient) Clone added in v1.2.0

func (c *JSONClient) Clone() *JSONClient

Clone will clone an instance of the JSONClient without references to the old one.

func (*JSONClient) DELETE

func (c *JSONClient) DELETE(ctx context.Context, url string, body interface{}, result interface{}) error

DELETE is an alias to do the Request with the http.MethodDelete method.

func (*JSONClient) GET

func (c *JSONClient) GET(ctx context.Context, url string, body interface{}, result interface{}) error

GET is an alias to do the Request with the http.MethodGet method.

Example
Output:

func (*JSONClient) HEAD

func (c *JSONClient) HEAD(ctx context.Context, url string, body interface{}, result interface{}) error

HEAD is an alias to do the Request with the http.MethodHead method.

func (*JSONClient) Method

func (c *JSONClient) Method(
	method string,
) func(ctx context.Context, url string, body interface{}, result interface{}) error

Method returns a function implementation of the HTTP Method from the Client by its name. Returns Client.GET as the default method.

func (*JSONClient) OPTIONS

func (c *JSONClient) OPTIONS(ctx context.Context, url string, body interface{}, result interface{}) error

OPTIONS is an alias to do the Request with the http.MethodOptions method.

func (*JSONClient) PATCH

func (c *JSONClient) PATCH(ctx context.Context, url string, body interface{}, result interface{}) error

PATCH is an alias to do the Request with the http.MethodPatch method.

func (*JSONClient) POST

func (c *JSONClient) POST(ctx context.Context, url string, body interface{}, result interface{}) error

POST is an alias to do the Request with the http.MethodPost method.

func (*JSONClient) PUT

func (c *JSONClient) PUT(ctx context.Context, url string, body interface{}, result interface{}) error

PUT is an alias to do the Request with the http.MethodPut method.

func (*JSONClient) Request

func (c *JSONClient) Request(
	ctx context.Context,
	method string,
	url string,
	body interface{},
	result interface{},
) (err error)

Request prepares the request by marshaling request body and tries to unmarshal response with the JSONClient.UnmarshalHTTPResponse function.

func (*JSONClient) TRACE

func (c *JSONClient) TRACE(ctx context.Context, url string, body interface{}, result interface{}) error

TRACE is an alias to do the Request with the http.MethodTrace method.

func (*JSONClient) UnmarshalHTTPResponse

func (c *JSONClient) UnmarshalHTTPResponse(response *http.Response, httpErr error, result interface{}) (err error)

UnmarshalHTTPResponse tries to unmarshal the response body into the given result interface. Result should be reference type and not nil.

type Middleware

type Middleware func(
	request *http.Request,
	next func(request *http.Request) (*http.Response, error),
) (*http.Response, error)

Middleware is an extended interface to the RoundTrip function of the http.RoundTripper interface.

type Option added in v1.2.0

type Option func(c *Client)

func WithCheckRedirect added in v1.2.0

func WithCheckRedirect(check func(req *http.Request, via []*http.Request) error) Option

WithCheckRedirect set the check redirect function for the http.Client

func WithCookieJar added in v1.2.0

func WithCookieJar(jar http.CookieJar) Option

WithCookieJar set the cookie jar for the http.Client

func WithMiddleware added in v1.2.0

func WithMiddleware(middleware ...Middleware) Option

WithMiddleware set middlewares for the client

func WithTimeout added in v1.2.0

func WithTimeout(timeout time.Duration) Option

WithTimeout set timeout for the http.Client

Directories

Path Synopsis
examples
Package middleware provides different types of middlewares for the cHTTP clients.
Package middleware provides different types of middlewares for the cHTTP clients.

Jump to

Keyboard shortcuts

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