Documentation
¶
Overview ¶
Package httpclient provides a fluent, builder-pattern HTTP client.
Simplifies HTTP request creation and response handling with a chainable API. Reduces boilerplate code while maintaining flexibility and type safety. Makes HTTP client code more readable, testable, and maintainable.
Index ¶
- func ParsePostForm(req *http.Request) error
- type API
- func (api *API) Clone() *API
- func (api *API) Delete(endpoint string) *RequestBuilder
- func (api *API) Do(ctx context.Context, req *RequestBuilder) *ResponseBuilder
- func (api *API) Execute(ctx context.Context, req *RequestBuilder) error
- func (api *API) Get(endpoint string) *RequestBuilder
- func (api *API) Head(endpoint string) *RequestBuilder
- func (api *API) Patch(endpoint string) *RequestBuilder
- func (api *API) Post(endpoint string) *RequestBuilder
- func (api *API) Put(endpoint string) *RequestBuilder
- func (api *API) URL(endpoint string) *url.URL
- func (api *API) WithRequestHeaders(headers http.Header) *API
- func (api *API) WithRequestOverrideFunc(overrideFunc RequestOverrideFunc) *API
- func (api *API) WithResponseBodySizeReadLimit(bodySizeReadLimit int64) *API
- func (api *API) WithResponseHandler(status int, handler ResponseHandler) *API
- type Doer
- type RequestBuilder
- func (b *RequestBuilder) AddHeader(key, value string, values ...string) *RequestBuilder
- func (b *RequestBuilder) AddHeaders(header http.Header) *RequestBuilder
- func (b *RequestBuilder) AddQueryParam(key, value string, values ...string) *RequestBuilder
- func (b *RequestBuilder) AddQueryParams(params url.Values) *RequestBuilder
- func (b *RequestBuilder) Client(client Doer) *RequestBuilder
- func (b *RequestBuilder) Do(ctx context.Context) *ResponseBuilder
- func (b *RequestBuilder) PathReplacer(pattern, replaceWith string) *RequestBuilder
- func (b *RequestBuilder) Request(ctx context.Context) (*http.Request, error)
- func (b *RequestBuilder) Send(body io.Reader) *RequestBuilder
- func (b *RequestBuilder) SendForm(values url.Values) *RequestBuilder
- func (b *RequestBuilder) SendJSON(obj any) *RequestBuilder
- func (b *RequestBuilder) SetHeader(key, value string, values ...string) *RequestBuilder
- func (b *RequestBuilder) SetHeaders(header http.Header) *RequestBuilder
- func (b *RequestBuilder) SetOverrideFunc(overrideFunc RequestOverrideFunc) *RequestBuilder
- func (b *RequestBuilder) SetQueryParam(key, value string, values ...string) *RequestBuilder
- func (b *RequestBuilder) SetQueryParams(params url.Values) *RequestBuilder
- type RequestOverrideFunc
- type ResponseBuilder
- func (b *ResponseBuilder) BodySizeReadLimit(bodySizeReadLimit int64) *ResponseBuilder
- func (b *ResponseBuilder) Error() error
- func (b *ResponseBuilder) ErrorOnStatus(status int, err error) *ResponseBuilder
- func (b *ResponseBuilder) OnStatus(status int, handler ResponseHandler) *ResponseBuilder
- func (b *ResponseBuilder) OnStatuses(statuses []int, handler ResponseHandler) *ResponseBuilder
- func (b *ResponseBuilder) ReceiveJSON(status int, dest any) *ResponseBuilder
- func (b *ResponseBuilder) SuccessOnStatus(statuses ...int) *ResponseBuilder
- type ResponseHandler
- type ResponseStatusHandlers
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ParsePostForm ¶
ParsePostForm parses request body as form data and populates req.PostForm. Extends standard library to handle non-standard HTTP methods.
Standard library only parses body for POST, PUT, PATCH. Other methods (like DELETE) ignore body even with form data. This function fills that gap.
Behavior:
- POST, PUT, PATCH: Delegates to standard req.ParseForm()
- Other methods: Manually parses request body as form data
- Idempotent (safe to call multiple times)
- Does nothing if req.PostForm already populated
Populates req.PostForm with parsed values.
Types ¶
type API ¶
type API struct {
// contains filtered or unexported fields
}
API stores configuration and defaults for HTTP requests to a specific service. It provides common attributes (headers, response handlers) applied to all requests.
API instances are safe for concurrent use as they create new builders for each request.
func NewAPI ¶
NewAPI creates an API instance with the provided client and server address.
The client must implement the Doer interface (http.Client does). Endpoint paths are appended to the server address.
func (*API) Clone ¶ added in v0.2.0
Clone creates a deep copy with independent configuration.
Headers, response handlers, and settings are copied. The HTTP client is shared.
func (*API) Delete ¶
func (api *API) Delete(endpoint string) *RequestBuilder
Delete creates a DELETE request builder with default headers and settings.
func (*API) Do ¶
func (api *API) Do(ctx context.Context, req *RequestBuilder) *ResponseBuilder
Do executes the request and returns a response builder with API defaults.
Applies default response handlers and body size limits. Use for custom response handling beyond Execute().
func (*API) Execute ¶
func (api *API) Execute(ctx context.Context, req *RequestBuilder) error
Execute performs the request using API defaults and returns any error.
Convenience method for simple success/failure handling. Use Do() for complex response processing.
func (*API) Get ¶
func (api *API) Get(endpoint string) *RequestBuilder
Get creates a GET request builder with default headers and settings.
func (*API) Head ¶
func (api *API) Head(endpoint string) *RequestBuilder
Head creates a HEAD request builder with default headers and settings.
func (*API) Patch ¶
func (api *API) Patch(endpoint string) *RequestBuilder
Patch creates a PATCH request builder with default headers and settings.
func (*API) Post ¶
func (api *API) Post(endpoint string) *RequestBuilder
Post creates a POST request builder with default headers and settings.
func (*API) Put ¶
func (api *API) Put(endpoint string) *RequestBuilder
Put creates a PUT request builder with default headers and settings.
func (*API) WithRequestHeaders ¶
WithRequestHeaders adds headers to all requests. Request-specific headers take precedence over API-level headers.
Provided headers are merged into existing headers, not replaced. Common uses: authentication, user agents, ...
func (*API) WithRequestOverrideFunc ¶ added in v0.2.0
func (api *API) WithRequestOverrideFunc(overrideFunc RequestOverrideFunc) *API
WithRequestOverrideFunc sets a function called for every request to modify the final http.Request before execution.
Useful for authentication, signing, or consistent request modifications.
func (*API) WithResponseBodySizeReadLimit ¶
WithResponseBodySizeReadLimit sets maximum bytes to read from response bodies. Security feature preventing memory exhaustion attacks.
Behavior:
- Larger Content-Length causes failure
- Unknown Content-Length stops at limit
- 0 uses Content-Length as limit
- Negative disables limit (use with caution)
func (*API) WithResponseHandler ¶
func (api *API) WithResponseHandler(status int, handler ResponseHandler) *API
WithResponseHandler sets a default handler for the specified status code. Called automatically unless overridden by request-specific handlers.
Useful for consistent error handling (e.g., 401 as authentication error).
type Doer ¶
Doer defines interface for executing HTTP requests. Allows httpclient to work with any HTTP client implementation. Standard http.Client implements this interface directly.
func DoerWrapDumpB64 ¶
DoerWrapDumpB64 wraps Doer with request/response dumping capability. Captures complete HTTP traffic (headers and bodies) as base64 strings.
Useful for debugging, logging, or testing HTTP traffic inspection. Dumps include all headers and body content.
If dumpFunc is nil, no dumping occurs but wrapper still applied. Uses httputil.DumpRequestOut and httputil.DumpResponse.
type RequestBuilder ¶
type RequestBuilder struct {
// contains filtered or unexported fields
}
RequestBuilder provides a fluent interface for building HTTP requests. Configure method, URL, headers, body through method chaining.
Not thread-safe. Each instance builds and executes a single request.
func NewRequest ¶
func NewRequest(method, endpoint string) *RequestBuilder
NewRequest creates a RequestBuilder for the HTTP method and endpoint URL.
Method should be valid (GET, POST, PUT, DELETE, etc.). Endpoint should be complete URL (containing scheme, host, endpoint, ...).
Parse errors are captured and returned when Request() or Do() is called.
func (*RequestBuilder) AddHeader ¶
func (b *RequestBuilder) AddHeader(key, value string, values ...string) *RequestBuilder
AddHeader appends values to header, preserving existing ones. Header names are canonicalized. Creates header if missing, appends if exists.
func (*RequestBuilder) AddHeaders ¶
func (b *RequestBuilder) AddHeaders(header http.Header) *RequestBuilder
AddHeaders appends all provided header values to existing ones. Use SetHeaders() to replace entirely.
func (*RequestBuilder) AddQueryParam ¶
func (b *RequestBuilder) AddQueryParam(key, value string, values ...string) *RequestBuilder
AddQueryParam appends values to query parameter, preserving existing ones. Creates parameter if missing, appends if exists.
func (*RequestBuilder) AddQueryParams ¶
func (b *RequestBuilder) AddQueryParams(params url.Values) *RequestBuilder
AddQueryParams appends all provided parameter values to existing ones. Use SetQueryParams() to replace entirely.
func (*RequestBuilder) Client ¶
func (b *RequestBuilder) Client(client Doer) *RequestBuilder
Client sets the HTTP client for request execution. Must implement Doer interface (http.Client does). Defaults to http.DefaultClient. Allows custom clients with timeouts, transports.
func (*RequestBuilder) Do ¶
func (b *RequestBuilder) Do(ctx context.Context) *ResponseBuilder
Do builds, executes request and returns ResponseBuilder.
func (*RequestBuilder) PathReplacer ¶
func (b *RequestBuilder) PathReplacer(pattern, replaceWith string) *RequestBuilder
PathReplacer replaces pattern occurrences in URL path with replacement. Keeps URLs readable and searchable. Example: NewRequest("PUT", "/users/{userID}/email").PathReplacer("{userID}", userID).
func (*RequestBuilder) Send ¶
func (b *RequestBuilder) Send(body io.Reader) *RequestBuilder
Send sets io.Reader as request body with Content-Type: application/octet-stream.
Useful for binary data, file uploads, or custom content.
func (*RequestBuilder) SendForm ¶
func (b *RequestBuilder) SendForm(values url.Values) *RequestBuilder
SendForm sets request body to form values as application/x-www-form-urlencoded. Sets appropriate Content-Type header.
Used for HTML forms and form-encoded API endpoints.
func (*RequestBuilder) SendJSON ¶
func (b *RequestBuilder) SendJSON(obj any) *RequestBuilder
SendJSON sets object as JSON request body and Content-Type header.
Marshaling is lazy - happens during execution, not when called. Object must be JSON-serializable. Marshal errors are returned during execution.
func (*RequestBuilder) SetHeader ¶
func (b *RequestBuilder) SetHeader(key, value string, values ...string) *RequestBuilder
SetHeader sets HTTP header values, replacing existing ones. Header names are canonicalized.
func (*RequestBuilder) SetHeaders ¶
func (b *RequestBuilder) SetHeaders(header http.Header) *RequestBuilder
SetHeaders merges multiple headers, replacing existing values for same keys. Other headers remain unchanged.
Equivalent to calling SetHeader for each provided header.
func (*RequestBuilder) SetOverrideFunc ¶ added in v0.2.0
func (b *RequestBuilder) SetOverrideFunc(overrideFunc RequestOverrideFunc) *RequestBuilder
SetOverrideFunc sets function called before request execution. Receives built request, returns modified request and error. Useful for authentication, signing, dynamic modifications.
func (*RequestBuilder) SetQueryParam ¶
func (b *RequestBuilder) SetQueryParam(key, value string, values ...string) *RequestBuilder
SetQueryParam sets query parameter values, replacing existing ones. Multiple values can be provided for the same parameter.
func (*RequestBuilder) SetQueryParams ¶
func (b *RequestBuilder) SetQueryParams(params url.Values) *RequestBuilder
SetQueryParams merges query parameters, replacing existing ones. Does not append; replaces entirely.
type RequestOverrideFunc ¶ added in v0.2.0
RequestOverrideFunc modifies an http.Request just before execution. Useful for authentication, signatures, or dynamic headers.
Returns modified request and error. Errors cause request failure.
type ResponseBuilder ¶
type ResponseBuilder struct {
// contains filtered or unexported fields
}
ResponseBuilder provides fluent interface for handling HTTP responses. Define status code processing, parse bodies, apply security constraints.
Not thread-safe. Each instance handles a single response.
func (*ResponseBuilder) BodySizeReadLimit ¶
func (b *ResponseBuilder) BodySizeReadLimit(bodySizeReadLimit int64) *ResponseBuilder
BodySizeReadLimit sets maximum bytes to read from response body. Security feature preventing memory exhaustion attacks.
Behavior:
- Positive: Max bytes. Larger Content-Length fails immediately.
- Zero: Uses Content-Length as limit.
- Negative: Disables limit (use with caution).
Without Content-Length header, reading stops at limit.
func (*ResponseBuilder) Error ¶
func (b *ResponseBuilder) Error() error
Error processes response with configured handlers and returns any error.
Call last in chain to finalize processing:
- Apply body size limits
- Call status handler
- Return error if no handler configured
Unhandled status codes return error with request details and base64 body.
func (*ResponseBuilder) ErrorOnStatus ¶
func (b *ResponseBuilder) ErrorOnStatus(status int, err error) *ResponseBuilder
ErrorOnStatus sets error for specific status code. Useful for mapping status codes to domain-specific sentinel errors.
func (*ResponseBuilder) OnStatus ¶
func (b *ResponseBuilder) OnStatus(status int, handler ResponseHandler) *ResponseBuilder
OnStatus sets custom handler for specific HTTP status code. Handler called when response matches status.
func (*ResponseBuilder) OnStatuses ¶
func (b *ResponseBuilder) OnStatuses(statuses []int, handler ResponseHandler) *ResponseBuilder
OnStatuses sets single handler for multiple status codes. Convenience method for shared handling logic.
func (*ResponseBuilder) ReceiveJSON ¶
func (b *ResponseBuilder) ReceiveJSON(status int, dest any) *ResponseBuilder
ReceiveJSON parses response body as JSON for specified status code. Stores result in provided destination.
Does not validate Content-Type header. Destination must be pointer.
func (*ResponseBuilder) SuccessOnStatus ¶
func (b *ResponseBuilder) SuccessOnStatus(statuses ...int) *ResponseBuilder
SuccessOnStatus marks status codes as successful (no error). Convenience method for success codes without special processing.
Equivalent to OnStatus with handler returning nil.
type ResponseHandler ¶
ResponseHandler handles HTTP responses for specific status codes.
type ResponseStatusHandlers ¶
type ResponseStatusHandlers map[int]ResponseHandler
ResponseStatusHandlers maps status codes to response handlers.