Documentation ¶
Index ¶
- Constants
- Variables
- func DecodeResOrErrRes(r *http.Response, goodOut, badOut any) ([]byte, error)
- func DecodeResponse(r *http.Response, out any) ([]byte, error)
- type Client
- func (c Client) Clone() Client
- func (c Client) Do(req *http.Request) (*http.Response, error)
- func (c Client) DoAndDecode(req *http.Request, out, errRes any) (*http.Response, error)
- func (c Client) DoReq(ctx context.Context, method string, r Request, out, errRes any) (*http.Response, error)
- func (c Client) Request(ctx context.Context, method, uri string, headers http.Header, body any) (*http.Request, error)
- func (c Client) With429Retry(v int) Client
- func (c Client) WithHeader(h http.Header) Client
- func (c Client) WithHost(v string) Client
- func (c Client) WithHttpClient(v httpClient) Client
- func (c Client) WithLogger(v LevelLogger) Client
- func (c Client) WithPathPrefix(v string) Client
- func (c Client) WithRateLimiter(v *RateLimiter) Client
- func (c Client) WithSetHeader(k string, v ...string) Client
- type LevelLogger
- type Path
- func (p Path) String() string
- func (p Path) WithBaseURL(url string) Path
- func (p Path) WithParam(param, value string) Path
- func (p Path) WithParams(params map[string]string) Path
- func (p Path) WithPrefix(basePath string) Path
- func (p Path) WithQuery(key string, values ...string) Path
- func (p Path) WithQueryArgs(args map[string]string) Path
- func (p Path) WithQueryValues(query url.Values) Path
- type RateLimitOption
- type RateLimiter
- func (r *RateLimiter) Burst() int
- func (r *RateLimiter) Do(ctx context.Context, doFn func() error) error
- func (r *RateLimiter) Limit() float64
- func (r *RateLimiter) SetBurst(burst int)
- func (r *RateLimiter) SetLimit(refillRate float64)
- func (r *RateLimiter) SlowDown()
- func (r *RateLimiter) SpeedUp()
- func (r *RateLimiter) Wait(ctx context.Context) error
- type ReqHeaders
- type Request
Examples ¶
Constants ¶
const ( HeaderReqID = "X-Request-ID" HeaderContentType = "Content-Type" ApplicationJSON = "application/json" Default429Retry = 2 )
const ( MaxAllowedCallsPerSecond = float64(math.MaxInt32) DefaultBurst = 1 DefaultCPSChangePercent = 0.1 // 10% )
Variables ¶
var ( ErrInvalidRequest = errors.New("request invalid") ErrNewRequestFail = errors.New("http.NewRequest failed") )
Functions ¶
func DecodeResOrErrRes ¶
func DecodeResponse ¶
DecodeResponse attempts to decode the response body into out it will however replace the response body so that it can be read again it also returns the body bytes so that you can debug if it did not work as expected
Types ¶
type Client ¶
type Client struct { ReqHeaders HttpClient httpClient // *http.Client Host string PathPrefix string RateLimiter *RateLimiter RetriesOn429 int // contains filtered or unexported fields }
func (Client) DoAndDecode ¶
func (Client) With429Retry ¶
func (Client) WithHttpClient ¶
func (Client) WithLogger ¶
func (c Client) WithLogger(v LevelLogger) Client
func (Client) WithPathPrefix ¶
func (Client) WithRateLimiter ¶
func (c Client) WithRateLimiter(v *RateLimiter) Client
type LevelLogger ¶
type Path ¶
type Path struct {
// contains filtered or unexported fields
}
Path builds a URL string which can be feed into url.Parse or http.NewRequest see the tests for all the different ways you can use it
Example ¶
package main import ( "fmt" "github.com/tempcke/httputil" ) func main() { const pathFoo = "/foo/:foo" uri := httputil.NewPath(pathFoo). WithParam(":foo", "bar") fmt.Println(uri.String()) }
Output: /foo/bar
func (Path) WithBaseURL ¶
func (Path) WithPrefix ¶
func (Path) WithQuery ¶
Example ¶
package main import ( "fmt" "github.com/tempcke/httputil" ) func main() { const pathFooBarBaz = "/foo/:foo/bar/:bar/:baz" uri := httputil.NewPath(pathFooBarBaz). WithBaseURL("https://example.com"). WithPrefix("v1"). WithParam(":foo", "p1"). WithParams(map[string]string{ "bar": "p2", "baz": "p3", }). WithQuery("id", "1", "2"). WithQuery("a", "A"). WithQueryArgs(map[string]string{ "b": "B", "c": "C", }) fmt.Println(uri.String()) }
Output: https://example.com/v1/foo/p1/bar/p2/p3?a=A&b=B&c=C&id=1&id=2
type RateLimitOption ¶
type RateLimitOption = func(*RateLimiter)
func RateLimitBurst ¶
func RateLimitBurst(burst int) RateLimitOption
func RateLimitChangePercent ¶
func RateLimitChangePercent(percent float64) RateLimitOption
type RateLimiter ¶
func NewRateLimiter ¶
func NewRateLimiter(limit float64, options ...RateLimitOption) *RateLimiter
NewRateLimiter uses rate.Limiter with a burst of 1 this means NewRateLimiter(10.0) will allow 1 call every 0.1 seconds and not 10 calls instantly and then 10 more calls in 1 second see comment on SetBurst for more information on limit and burst
func (*RateLimiter) Burst ¶
func (r *RateLimiter) Burst() int
func (*RateLimiter) Limit ¶
func (r *RateLimiter) Limit() float64
func (*RateLimiter) SetBurst ¶
func (r *RateLimiter) SetBurst(burst int)
SetBurst sets the burst on the limiter be warned that burst may not behave the way you would expect so rate.NewLimiter(rate.Limit(10.0), 10) would allow 20 calls in the first second but only 10 calls in the next second when the calls are all concurrent to help you reason about this... burst is bucketSize, and each call drains the bucket limit is refillRate, the rate at which the bucket is refilled
func (*RateLimiter) SetLimit ¶
func (r *RateLimiter) SetLimit(refillRate float64)
SetLimit sets the refill rate on the limiter be warned that this is really only an absolute limit when burst=1 read the comment on SetBurst for more information
func (*RateLimiter) SlowDown ¶
func (r *RateLimiter) SlowDown()
SlowDown reduces the bucket refill rate by 10% unless you have defined a different changePercent this is useful to auto adapt to 429 response codes
func (*RateLimiter) SpeedUp ¶
func (r *RateLimiter) SpeedUp()
type ReqHeaders ¶
type ReqHeaders struct { ReqID string // optional req header // contains filtered or unexported fields }
func (*ReqHeaders) AddHeader ¶
func (r *ReqHeaders) AddHeader(key string, vals ...string)
func (*ReqHeaders) Clone ¶
func (r *ReqHeaders) Clone() ReqHeaders
func (*ReqHeaders) Header ¶
func (r *ReqHeaders) Header() http.Header
func (*ReqHeaders) SetHeader ¶
func (r *ReqHeaders) SetHeader(key string, vals ...string)