klient

package module
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Aug 21, 2023 License: MIT Imports: 14 Imported by: 29

README

klient

License Coverage GitHub Workflow Status Go Report Card Go PKG

Retryable http client with some helper functions.

go get github.com/worldline-go/klient

Usage

Create a new client with a base url.

client, err := klient.New(klient.OptionClient.WithBaseURL("https://api.punkapi.com/v2/"))
if err != nil {
    // handle error
}

Set an API's struct with has client.

type BeerAPI struct {
	klient *klient.Client
}

type RandomRequest struct{}

func (RandomRequest) Method() string {
	return http.MethodGet
}

func (RandomRequest) Path() string {
	return "beers/random"
}

type RandomRequestResponse struct {
	Name string `json:"name"`
}

func (c BeerAPI) GetRandomBeer(ctx context.Context) ([]RandomRequestResponse, error) {
	var v []RandomRequestResponse

	if err := c.klient.DoWithFunc(ctx, RandomRequest{}, func(r *http.Response) error {
		if r.StatusCode != http.StatusOK {
			return klient.UnexpectedResponseError(r)
		}

		return json.NewDecoder(r.Body).Decode(&v)
	}); err != nil {
		return nil, err
	}

	return v, nil
}

Now you need to create a new instance of your API and use it.

api := BeerAPI{
    klient: client,
}

respond, err := api.GetRandomBeer(ctx)
if err != nil {
    // handle error
}

Documentation

Overview

Example
package main

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"net/http/httptest"

	"github.com/worldline-go/klient"
)

type Client struct {
	klient *klient.Client
}

func (c *Client) CreateX(ctx context.Context, r CreateXRequest) (*CreateXResponse, error) {
	var v CreateXResponse
	if err := c.klient.DoWithFunc(ctx, r, func(r *http.Response) error {
		if r.StatusCode != http.StatusOK {
			return klient.UnexpectedResponseError(r)
		}

		if err := json.NewDecoder(r.Body).Decode(&v); err != nil {
			return err
		}

		return nil
	}); err != nil {
		return nil, err
	}

	return &v, nil
}

// ----

type CreateXRequest struct {
	ID string `json:"id"`
}

func (CreateXRequest) Method() string {
	return http.MethodPost
}

func (CreateXRequest) Path() string {
	return "/api/v1/x"
}

func (r CreateXRequest) BodyJSON() interface{} {
	return r
}

func (r CreateXRequest) Validate() error {
	if r.ID == "" {
		return fmt.Errorf("id is required")
	}

	return nil
}

func (r CreateXRequest) Header() http.Header {
	v := http.Header{}
	v.Set("X-Info", "example")

	return v
}

type CreateXResponse struct {
	RequestID string `json:"request_id"`
}

// ---

func main() {
	httpServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// check request method
		if r.Method != http.MethodPost {
			w.WriteHeader(http.StatusBadRequest)
			w.Write([]byte(`{"error": "invalid request method"}`))
			return
		}

		// check request path
		if r.URL.Path != "/api/v1/x" {
			w.WriteHeader(http.StatusBadRequest)
			w.Write([]byte(`{"error": "invalid request path"}`))
			return
		}

		// check request header
		if r.Header.Get("X-Info") != "example" {
			w.WriteHeader(http.StatusBadRequest)
			w.Write([]byte(`{"error": "invalid request header"}`))
			return
		}

		// get request body
		var m map[string]interface{}
		if err := json.NewDecoder(r.Body).Decode(&m); err != nil {
			w.WriteHeader(http.StatusBadRequest)
			w.Write([]byte(`{"error": "invalid request body"}`))
			return
		}

		// check request body
		if m["id"] != "123" {
			w.WriteHeader(http.StatusBadRequest)
			w.Write([]byte(`{"error": "invalid id"}`))
			return
		}

		// write response
		w.WriteHeader(http.StatusOK)
		w.Write([]byte(`{"request_id": "123+"}`))
	}))

	defer httpServer.Close()

	httpxClient, err := klient.New(
		klient.OptionClient.WithBaseURL(httpServer.URL),
	)
	if err != nil {
		fmt.Println(err)
		return
	}

	c := &Client{
		klient: httpxClient,
	}

	v, err := c.CreateX(context.Background(), CreateXRequest{
		ID: "123",
	})
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(v.RequestID)
}
Output:

123+

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrValidating      = fmt.Errorf("failed to validate request")
	ErrMarshal         = fmt.Errorf("failed to marshal request body")
	ErrRequest         = fmt.Errorf("failed to do request")
	ErrResponseFuncNil = fmt.Errorf("response function is nil")
)
View Source
var OptionClient = OptionClientHolder{}
View Source
var OptionRetry = OptionRetryHolder{}
View Source
var ResponseErrLimit int64 = 1 << 20 // 1MB

Functions

func LimitedResponse

func LimitedResponse(resp *http.Response) []byte

LimitedResponse not close body, retry library draining it.

func NewRetryPolicy

func NewRetryPolicy(opts ...optionRetryFn) retryablehttp.CheckRetry

func Request

func Request(ctx context.Context, baseURL, method, path string, body io.Reader, header http.Header, fn func(*http.Response) error) error

Request sends an HTTP request and calls the response function with the global client.

func RetryPolicy

func RetryPolicy(ctx context.Context, resp *http.Response, err error) (bool, error)

RetryPolicy provides a default callback for Client.CheckRetry, which will retry on connection errors and server errors.

func UnexpectedResponse

func UnexpectedResponse(resp *http.Response) error

UnexpectedResponse returns an error if the response status code is not 2xx.

func UnexpectedResponseError

func UnexpectedResponseError(resp *http.Response) error

UnexpectedResponseError returns an error with the response body.

Types

type Client

type Client struct {
	HTTPClient *http.Client

	BaseURL *url.URL
	// contains filtered or unexported fields
}

func New

func New(opts ...optionClientFn) (*Client, error)

New creates a new http client with the provided options.

Default BaseURL is required, it can be disabled by setting DisableBaseURLCheck to true.

func (*Client) Do

func (c *Client) Do(ctx context.Context, req InfRequest, resp interface{}) error

Do sends an HTTP request and json unmarshals the response body to data.

Do work same as DoWithFunc with defaultResponseFunc.

func (*Client) DoWithFunc

func (c *Client) DoWithFunc(ctx context.Context, req InfRequest, fn func(*http.Response) error) error

DoWithFunc sends an HTTP request and calls the response function.

Request additional implements InfRequestValidator, InfQueryStringGenerator, InfHeader, InfBody, InfBodyJSON.

func (*Client) Request

func (c *Client) Request(ctx context.Context, method, path string, body io.Reader, header http.Header, fn func(*http.Response) error) error

Request sends an HTTP request and calls the response function.

type InfBody

type InfBody interface {
	// Body returns the body to be sent.
	Body() io.Reader
}

type InfBodyJSON

type InfBodyJSON interface {
	// BodyJSON can return any type that can be marshaled to JSON.
	// Automatically sets Content-Type to application/json.
	BodyJSON() interface{}
}

type InfHeader

type InfHeader interface {
	// Header returns the header to be sent.
	Header() http.Header
}

type InfQueryStringGenerator

type InfQueryStringGenerator interface {
	// ToQuery returns the query string to be sent.
	ToQuery() url.Values
}

type InfRequest

type InfRequest interface {
	// Method returns the HTTP method.
	Method() string
	// Path returns the path to be sent.
	Path() string
}

InfRequest is the base interface for all requests.

type InfRequestValidator

type InfRequestValidator interface {
	// Validate returns error if request is invalid.
	Validate() error
}

type Null

type Null[T any] struct {
	Value T
	Valid bool
}

type OptionClientHolder added in v0.1.1

type OptionClientHolder struct{}

func (OptionClientHolder) WithBackoff added in v0.1.1

func (OptionClientHolder) WithBackoff(backoff retryablehttp.Backoff) optionClientFn

WithBackoff configures the client to use the provided backoff.

func (OptionClientHolder) WithBaseURL added in v0.1.1

func (OptionClientHolder) WithBaseURL(baseURL string) optionClientFn

WithBaseURL configures the client to use the provided base URL.

func (OptionClientHolder) WithCtx added in v0.1.1

func (OptionClientHolder) WithCtx(ctx context.Context) optionClientFn

WithCtx for TransportWrapper call.

func (OptionClientHolder) WithDisableBaseURLCheck added in v0.1.1

func (OptionClientHolder) WithDisableBaseURLCheck(baseURLCheck bool) optionClientFn

WithDisableBaseURLCheck configures the client to disable base URL check.

func (OptionClientHolder) WithDisableRetry added in v0.1.1

func (OptionClientHolder) WithDisableRetry(disableRetry bool) optionClientFn

WithDisableRetry configures the client to disable retry.

func (OptionClientHolder) WithHTTPClient added in v0.1.1

func (OptionClientHolder) WithHTTPClient(httpClient *http.Client) optionClientFn

WithHTTPClient configures the client to use the provided http client.

func (OptionClientHolder) WithInsecureSkipVerify added in v0.1.1

func (OptionClientHolder) WithInsecureSkipVerify(insecureSkipVerify bool) optionClientFn

WithInsecureSkipVerify configures the client to skip TLS verification.

func (OptionClientHolder) WithLogger added in v0.1.1

func (OptionClientHolder) WithLogger(logger zerolog.Logger) optionClientFn

WithLogger configures the client to use the provided logger.

func (OptionClientHolder) WithMaxConnections added in v0.1.1

func (OptionClientHolder) WithMaxConnections(maxConnections int) optionClientFn

WithMaxConnections configures the client to use the provided maximum number of idle connections.

func (OptionClientHolder) WithPooledClient added in v0.1.1

func (OptionClientHolder) WithPooledClient(pooledClient bool) optionClientFn

func (OptionClientHolder) WithRetryLog added in v0.1.1

func (OptionClientHolder) WithRetryLog(retryLog bool) optionClientFn

WithRetryLog configures the client to use the provided retry log flag, default is true.

This option is only used with default retry policy.

func (OptionClientHolder) WithRetryMax added in v0.1.1

func (OptionClientHolder) WithRetryMax(retryMax int) optionClientFn

WithRetryMax configures the client to use the provided maximum number of retry.

func (OptionClientHolder) WithRetryOptions added in v0.1.1

func (OptionClientHolder) WithRetryOptions(opts ...optionRetryFn) optionClientFn

func (OptionClientHolder) WithRetryPolicy added in v0.1.1

func (OptionClientHolder) WithRetryPolicy(retryPolicy retryablehttp.CheckRetry) optionClientFn

WithRetryPolicy configures the client to use the provided retry policy.

func (OptionClientHolder) WithRetryWaitMax added in v0.1.1

func (OptionClientHolder) WithRetryWaitMax(retryWaitMax time.Duration) optionClientFn

WithRetryWaitMax configures the client to use the provided maximum wait time.

func (OptionClientHolder) WithRetryWaitMin added in v0.1.1

func (OptionClientHolder) WithRetryWaitMin(retryWaitMin time.Duration) optionClientFn

WithRetryWaitMin configures the client to use the provided minimum wait time.

func (OptionClientHolder) WithTransportWrapper added in v0.1.1

func (OptionClientHolder) WithTransportWrapper(f func(context.Context, http.RoundTripper) (http.RoundTripper, error)) optionClientFn

WithTransportWrapper configures the client to wrap the default transport.

type OptionRetryHolder added in v0.1.1

type OptionRetryHolder struct{}

func (OptionRetryHolder) WithOptionRetry added in v0.1.1

func (OptionRetryHolder) WithOptionRetry(oRetry *OptionRetryValue) optionRetryFn

WithOptionRetry configures the retry policy directly.

This option overrides all other retry options when previously set.

func (OptionRetryHolder) WithRetryDisable added in v0.1.1

func (OptionRetryHolder) WithRetryDisable() optionRetryFn

func (OptionRetryHolder) WithRetryDisabledStatusCodes added in v0.1.1

func (OptionRetryHolder) WithRetryDisabledStatusCodes(codes ...int) optionRetryFn

func (OptionRetryHolder) WithRetryEnabledStatusCodes added in v0.1.1

func (OptionRetryHolder) WithRetryEnabledStatusCodes(codes ...int) optionRetryFn

func (OptionRetryHolder) WithRetryLog added in v0.1.1

func (OptionRetryHolder) WithRetryLog(log logz.Adapter) optionRetryFn

type OptionRetryValue

type OptionRetryValue = optionRetryValue

Directories

Path Synopsis
example
api command

Jump to

Keyboard shortcuts

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