Documentation
¶
Overview ¶
Example ¶
Example demonstrates basic usage of the client. This is a runnable example, but it will not make a real network call as the URL is a placeholder. To make it a "godoc" example, we'd typically mock the server.
package main
import (
"fmt"
"github.com/graingo/maltose/net/mclient"
)
func main() {
client := mclient.New()
// In a real scenario, you would handle the response and error.
_, err := client.R().
SetHeader("Accept", "application/json").
Get("https://api.example.com/users")
if err != nil {
// This will likely print an error in a test environment, which is expected.
fmt.Println("Request intended to fail for example purposes.")
}
}
Output: Request intended to fail for example purposes.
Example (CustomRetryCondition) ¶
Example_customRetryCondition demonstrates custom retry conditions.
package main
import (
"fmt"
"net/http"
"github.com/graingo/maltose/net/mclient"
)
func main() {
client := mclient.New()
// Define custom retry condition
customRetryCondition := func(resp *http.Response, err error) bool {
// Retry on network errors
if err != nil {
return true
}
// Retry on server errors (5xx) or rate limiting (429)
if resp != nil && (resp.StatusCode >= 500 || resp.StatusCode == 429) {
return true
}
return false
}
config := mclient.RetryConfig{Count: 3}
_, err := client.R().
SetRetry(config).
SetRetryCondition(customRetryCondition).
Get("https://api.example.com/users")
if err != nil {
fmt.Println("Custom retry example finished.")
}
}
Output: Custom retry example finished.
Example (JSON) ¶
Example_jSON demonstrates JSON request and response handling.
package main
import (
"fmt"
"github.com/graingo/maltose/net/mclient"
)
func main() {
client := mclient.New()
// Define request and response structures
type User struct {
Name string `json:"name"`
Email string `json:"email"`
}
type CreateResponse struct {
ID int `json:"id"`
Name string `json:"name"`
Status string `json:"status"`
}
// Prepare request data
user := User{
Name: "John Doe",
Email: "john@example.com",
}
// Prepare result container
var result CreateResponse
// Send request (this will fail as the URL is not real)
_, err := client.R().
SetBody(user).
SetResult(&result).
Post("https://api.example.com/users")
if err != nil {
fmt.Println("JSON request example finished.")
}
// In a real case, you might print the result:
// fmt.Printf("Created user: %s (ID: %d)\n", result.Name, result.ID)
}
Output: JSON request example finished.
Example (Middleware) ¶
Example_middleware demonstrates middleware usage.
package main
import (
"fmt"
"log"
"github.com/graingo/maltose/net/mclient"
)
func main() {
client := mclient.New()
// Add auth middleware
client.Use(mclient.MiddlewareFunc(func(next mclient.HandlerFunc) mclient.HandlerFunc {
return func(req *mclient.Request) (*mclient.Response, error) {
req.SetHeader("Authorization", "Bearer test-token")
return next(req)
}
}))
// Add logging middleware
client.Use(mclient.MiddlewareFunc(func(next mclient.HandlerFunc) mclient.HandlerFunc {
return func(req *mclient.Request) (*mclient.Response, error) {
log.Printf("Sending request to %s", req.Request.URL.String())
resp, err := next(req)
if err != nil {
log.Printf("Request failed: %v", err)
}
return resp, err
}
}))
_, err := client.R().Get("https://api.example.com/users")
if err != nil {
fmt.Println("Middleware example finished.")
}
}
Output: Middleware example finished.
Example (Retry) ¶
Example_retry demonstrates retry mechanism.
package main
import (
"fmt"
"time"
"github.com/graingo/maltose/net/mclient"
)
func main() {
client := mclient.New()
// Configure retry strategy
config := mclient.RetryConfig{
Count: 3,
BaseInterval: time.Second,
MaxInterval: 30 * time.Second,
BackoffFactor: 2.0,
JitterFactor: 0.1,
}
// Send request with retry (this will fail as the URL is not real)
_, err := client.R().
SetRetry(config).
Get("https://api.example.com/users")
if err != nil {
fmt.Println("Retry example finished.")
}
}
Output: Retry example finished.
Index ¶
- Variables
- type Client
- func (c *Client) Clone() *Client
- func (c *Client) GetClient() *http.Client
- func (c *Client) NewRequest() *Request
- func (c *Client) R() *Request
- func (c *Client) SetAgent(agent string) *Client
- func (c *Client) SetBaseURL(baseURL string) *Client
- func (c *Client) SetBasicAuth(username, password string) *Client
- func (c *Client) SetBrowserMode(enabled bool) *Client
- func (c *Client) SetConfig(config ClientConfig) *Client
- func (c *Client) SetContentType(contentType string) *Client
- func (c *Client) SetCookie(key, value string) *Client
- func (c *Client) SetCookieMap(m map[string]string) *Client
- func (c *Client) SetHeader(key, value string) *Client
- func (c *Client) SetHeaderMap(m map[string]string) *Client
- func (c *Client) SetRedirectLimit(redirectLimit int) *Client
- func (c *Client) SetTLSConfig(tlsConfig *tls.Config) error
- func (c *Client) SetTLSKeyCrt(crtFile, keyFile string) error
- func (c *Client) SetTimeout(t time.Duration) *Client
- func (c *Client) SetTransport(transport http.RoundTripper) *Client
- func (c *Client) Use(middlewares ...MiddlewareFunc) *Client
- func (c *Client) WithGlobalRateLimit(rps float64, burst int) *Client
- type ClientConfig
- type HandlerFunc
- type MiddlewareFunc
- type RateLimitConfig
- type RateLimiter
- type Request
- func (r *Request) ContentType(contentType string) *Request
- func (r *Request) Delete(url string) (*Response, error)
- func (r *Request) Do() (*Response, error)deprecated
- func (r *Request) Get(url string) (*Response, error)
- func (r *Request) GetRequest() *http.Request
- func (r *Request) GetResponse() *Response
- func (r *Request) Head(url string) (*Response, error)
- func (r *Request) Method(method string) *Request
- func (r *Request) Options(url string) (*Response, error)
- func (r *Request) Patch(url string) (*Response, error)
- func (r *Request) Post(url string) (*Response, error)
- func (r *Request) Put(url string) (*Response, error)
- func (r *Request) Send(url string) (*Response, error)
- func (r *Request) SetBody(body any) *Request
- func (r *Request) SetContext(ctx context.Context) *Request
- func (r *Request) SetError(err any) *Request
- func (r *Request) SetForm(key, value string) *Request
- func (r *Request) SetFormMap(params map[string]string) *Request
- func (r *Request) SetHeader(key, value string) *Request
- func (r *Request) SetHeaders(headers map[string]string) *Request
- func (r *Request) SetQuery(key, value string) *Request
- func (r *Request) SetQueryMap(params map[string]string) *Request
- func (r *Request) SetResponse(resp *Response)
- func (r *Request) SetResult(result any) *Request
- func (r *Request) SetRetry(config RetryConfig) *Request
- func (r *Request) SetRetryCondition(condition func(*http.Response, error) bool) *Request
- func (r *Request) SetRetrySimple(count int, baseInterval time.Duration) *Request
- func (r *Request) URL(url string) *Request
- func (r *Request) Use(middlewares ...MiddlewareFunc) *Request
- type Response
- func (r *Response) Close() error
- func (r *Response) GetCookie(key string) string
- func (r *Response) GetCookieMap() map[string]string
- func (r *Response) GetCookies() map[string]string
- func (r *Response) GetError() any
- func (r *Response) GetResult() any
- func (r *Response) IsSuccess() bool
- func (r *Response) Parse(result interface{}) error
- func (r *Response) ReadAll() []byte
- func (r *Response) ReadAllString() string
- func (r *Response) SetBodyContent(content []byte)
- func (r *Response) SetError(err interface{})
- func (r *Response) SetResult(result interface{})
- type RetryConfig
- type TokenBucketLimiter
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var LogMaxBodySize = -1
Functions ¶
This section is empty.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is an HTTP client with enhanced features.
func New ¶
func New() *Client
New creates and returns a new HTTP client object. It comes with a set of default internal middlewares for recovery, tracing, and metrics.
func NewWithConfig ¶
func NewWithConfig(config ClientConfig) *Client
NewWithConfig creates and returns a client with given config. Note that the internal middlewares (recovery, trace, metric) are still applied.
func (*Client) NewRequest ¶
NewRequest creates and returns a new request object.
func (*Client) SetBaseURL ¶
SetBaseURL sets the base URL for all requests.
func (*Client) SetBasicAuth ¶
SetBasicAuth sets HTTP basic authentication for the client.
func (*Client) SetBrowserMode ¶
SetBrowserMode enables browser mode of the client. When browser mode is enabled, it automatically saves and sends cookie content from and to server via an in-memory cookie jar.
func (*Client) SetConfig ¶
func (c *Client) SetConfig(config ClientConfig) *Client
SetConfig sets the client configuration.
func (*Client) SetContentType ¶
SetContentType sets HTTP content type for the client.
func (*Client) SetCookieMap ¶
SetCookieMap sets cookie items with map.
func (*Client) SetHeaderMap ¶
SetHeaderMap sets custom HTTP headers with map.
func (*Client) SetRedirectLimit ¶
SetRedirectLimit limits the number of jumps for redirection. It sets the CheckRedirect function on the underlying http.Client. A limit of 0 means no redirects will be followed.
func (*Client) SetTLSConfig ¶
SetTLSConfig sets the client's TLS configuration.
func (*Client) SetTLSKeyCrt ¶
SetTLSKeyCrt sets client TLS certificate and key files.
func (*Client) SetTimeout ¶
SetTimeout sets the request timeout for the client.
func (*Client) SetTransport ¶
func (c *Client) SetTransport(transport http.RoundTripper) *Client
SetTransport sets the client transport.
func (*Client) Use ¶
func (c *Client) Use(middlewares ...MiddlewareFunc) *Client
Use adds middleware handlers to the client.
type ClientConfig ¶
type ClientConfig struct {
// BaseURL specifies the base URL for all requests.
BaseURL string `mconv:"base_url"`
// Timeout specifies a time limit for requests made by this client.
Timeout time.Duration `mconv:"timeout"`
// Transport specifies the mechanism by which individual HTTP requests are made.
Transport http.RoundTripper
// Header specifies the default header for requests.
Header http.Header
}
ClientConfig is the configuration for Client.
type HandlerFunc ¶
HandlerFunc defines the handler used by middleware.
type MiddlewareFunc ¶
type MiddlewareFunc func(HandlerFunc) HandlerFunc
MiddlewareFunc is the function type for middleware.
func MiddlewareLog ¶
func MiddlewareLog(logger *mlog.Logger) MiddlewareFunc
MiddlewareLog creates a middleware that logs request and response details in two steps: 1. Before the request is sent ("started"). 2. After the request is completed ("finished" or "error"). This allows for better observability, especially for hanging requests.
func MiddlewareRateLimit ¶
func MiddlewareRateLimit(config RateLimitConfig) MiddlewareFunc
MiddlewareRateLimit returns a middleware that limits the rate of requests.
type RateLimitConfig ¶
type RateLimitConfig struct {
// RequestsPerSecond is the number of requests allowed per second
RequestsPerSecond float64
// Burst is the maximum number of requests allowed to happen at once
Burst int
// Skip determines if rate limiting should be skipped for a request
Skip func(*Request) bool
// ErrorHandler handles rate limit errors
ErrorHandler func(context.Context, error) (*Response, error)
}
RateLimitConfig represents options for rate limiting middleware.
type RateLimiter ¶
type RateLimiter interface {
// Wait blocks until a request can be allowed or context is cancelled.
Wait(ctx context.Context) error
// TryAcquire tries to acquire a token without blocking.
TryAcquire() bool
}
RateLimiter defines the interface for rate limiters.
type Request ¶
type Request struct {
*http.Request // Request is the underlying http.Request object.
// contains filtered or unexported fields
}
Request is the struct for client request.
func (*Request) ContentType ¶
ContentType sets the Content-Type header for the request.
func (*Request) Do
deprecated
func (*Request) GetRequest ¶
GetRequest returns the *http.Request object.
func (*Request) GetResponse ¶
GetResponse returns the response object of this request.
func (*Request) Options ¶ added in v0.1.2
Options sets the method to OPTIONS and executes the request.
func (*Request) Send ¶
Send performs a request with the chain style API. If the method is not specified, it defaults to GET.
func (*Request) SetContext ¶
SetContext sets the context for the request. It creates a new underlying http.Request with the given context.
func (*Request) SetFormMap ¶
SetFormMap sets multiple form parameters from a map.
func (*Request) SetHeader ¶
SetHeader sets a header key-value pair for the request. This is an alias of Header method for better chain API compatibility.
func (*Request) SetHeaders ¶
SetHeaders sets multiple headers at once.
func (*Request) SetQueryMap ¶
SetQueryMap sets multiple query parameters from a map.
func (*Request) SetResponse ¶
SetResponse sets the response object for this request.
func (*Request) SetRetry ¶
func (r *Request) SetRetry(config RetryConfig) *Request
SetRetry sets retry configuration.
func (*Request) SetRetryCondition ¶
SetRetryCondition sets a custom retry condition function. The function takes the HTTP response and error as input and returns true if the request should be retried.
func (*Request) SetRetrySimple ¶
SetRetrySimple sets retry count and base interval with default backoff and jitter.
func (*Request) Use ¶
func (r *Request) Use(middlewares ...MiddlewareFunc) *Request
Use adds middleware handlers to the request.
type Response ¶
type Response struct {
*http.Response // Response is the underlying http.Response object of certain request.
// contains filtered or unexported fields
}
Response is the struct for client request response.
func (*Response) GetCookieMap ¶
GetCookieMap retrieves and returns a copy of current cookie values map.
func (*Response) GetCookies ¶
GetCookies retrieves and returns all cookie values.
func (*Response) IsSuccess ¶
IsSuccess returns whether the response status code is in the 2xx range, indicating that the request was successfully received, understood, and accepted.
func (*Response) ReadAllString ¶
ReadAllString retrieves and returns the response content as string.
func (*Response) SetBodyContent ¶
SetBodyContent overwrites response content with custom one.
type RetryConfig ¶
type RetryConfig struct {
// Count is the maximum number of retries.
// For example, if Count is 3, the request will be tried up to 4 times (initial attempt + 3 retries).
Count int
// BaseInterval is the base interval between retries.
// This is the starting point for calculating the delay between retries.
// For example, if BaseInterval is 1 second, the first retry will wait at least 1 second.
BaseInterval time.Duration
// MaxInterval is the maximum interval between retries.
// This prevents the delay from growing too large due to exponential backoff.
// For example, if MaxInterval is 30 seconds, even if the calculated delay is 60 seconds,
// the actual delay will be capped at 30 seconds.
MaxInterval time.Duration
// BackoffFactor is the factor for exponential backoff.
// Each retry's delay is calculated by multiplying the previous delay by this factor.
// For example, if BaseInterval is 1 second and BackoffFactor is 2.0:
// - First retry: 1 second
// - Second retry: 2 seconds
// - Third retry: 4 seconds
// - And so on...
BackoffFactor float64
// JitterFactor is the factor for random jitter.
// This adds randomness to the delay to prevent multiple clients from retrying simultaneously.
// The actual jitter is calculated as: delay * JitterFactor * (random number between -1 and 1)
// For example, if the calculated delay is 1 second and JitterFactor is 0.1:
// - The actual delay will be between 0.9 and 1.1 seconds
// A value of 0 means no jitter will be added.
JitterFactor float64
}
RetryConfig is the configuration for request retry.
func DefaultRetryConfig ¶
func DefaultRetryConfig() RetryConfig
DefaultRetryConfig returns the default retry configuration. The default values are: - Count: 3 retries - BaseInterval: 1 second - MaxInterval: 30 seconds - BackoffFactor: 2.0 (doubles the delay each time) - JitterFactor: 0.1 (adds ±10% random jitter)
type TokenBucketLimiter ¶
type TokenBucketLimiter struct {
// contains filtered or unexported fields
}
TokenBucketLimiter implements a token bucket rate limiter.
func NewTokenBucketLimiter ¶
func NewTokenBucketLimiter(rate float64, bucketSize int) *TokenBucketLimiter
NewTokenBucketLimiter creates a new token bucket rate limiter. The rate is specified in requests per second, and bucketSize determines the maximum burst size.
func (*TokenBucketLimiter) TryAcquire ¶
func (l *TokenBucketLimiter) TryAcquire() bool
TryAcquire attempts to take a token from the bucket without blocking. Returns true if a token was successfully taken, false otherwise.
Source Files
¶
- mclient.go
- mclient_config.go
- mclient_middleware.go
- mclient_middleware_internal.go
- mclient_middleware_internal_metric.go
- mclient_middleware_log.go
- mclient_middleware_ratelimit.go
- mclient_request.go
- mclient_request_exec.go
- mclient_request_header.go
- mclient_request_http.go
- mclient_request_params.go
- mclient_request_retry.go
- mclient_response.go