package httpx import ( "log/slog" "net/http" "time" "git.codelab.vc/pkg/httpx/balancer" "git.codelab.vc/pkg/httpx/circuitbreaker" "git.codelab.vc/pkg/httpx/middleware" "git.codelab.vc/pkg/httpx/retry" ) type clientOptions struct { baseURL string timeout time.Duration transport http.RoundTripper logger *slog.Logger errorMapper ErrorMapper middlewares []middleware.Middleware retryOpts []retry.Option enableRetry bool cbOpts []circuitbreaker.Option enableCB bool endpoints []balancer.Endpoint balancerOpts []balancer.Option maxResponseBody int64 } // Option configures a Client. type Option func(*clientOptions) // WithBaseURL sets the base URL prepended to all relative request paths. func WithBaseURL(url string) Option { return func(o *clientOptions) { o.baseURL = url } } // WithTimeout sets the overall request timeout. func WithTimeout(d time.Duration) Option { return func(o *clientOptions) { o.timeout = d } } // WithTransport sets the base http.RoundTripper. Defaults to http.DefaultTransport. func WithTransport(rt http.RoundTripper) Option { return func(o *clientOptions) { o.transport = rt } } // WithLogger enables structured logging of requests and responses. func WithLogger(l *slog.Logger) Option { return func(o *clientOptions) { o.logger = l } } // WithErrorMapper sets a function that maps HTTP responses to errors. func WithErrorMapper(m ErrorMapper) Option { return func(o *clientOptions) { o.errorMapper = m } } // WithMiddleware appends user middlewares to the chain. // These run between logging and retry in the middleware stack. func WithMiddleware(mws ...middleware.Middleware) Option { return func(o *clientOptions) { o.middlewares = append(o.middlewares, mws...) } } // WithRetry enables retry with the given options. func WithRetry(opts ...retry.Option) Option { return func(o *clientOptions) { o.enableRetry = true o.retryOpts = opts } } // WithCircuitBreaker enables per-host circuit breaking. func WithCircuitBreaker(opts ...circuitbreaker.Option) Option { return func(o *clientOptions) { o.enableCB = true o.cbOpts = opts } } // WithEndpoints sets the endpoints for load balancing. func WithEndpoints(eps ...balancer.Endpoint) Option { return func(o *clientOptions) { o.endpoints = eps } } // WithBalancer configures the load balancer strategy and options. func WithBalancer(opts ...balancer.Option) Option { return func(o *clientOptions) { o.balancerOpts = opts } } // WithMaxResponseBody limits the number of bytes read from response bodies // by Response.Bytes (and by extension String, JSON, XML). If the response // body exceeds n bytes, reading stops and returns an error. // A value of 0 means no limit (the default). func WithMaxResponseBody(n int64) Option { return func(o *clientOptions) { o.maxResponseBody = n } }