Documentation
¶
Overview ¶
Package httparty is a pure-Go (CGO-free) model of the behaviour of Ruby's `httparty` gem — the popular HTTP client DSL over Net::HTTP: the module verb methods (HTTParty.get/post/put/patch/delete/head/options), the `include HTTParty` class DSL (base_uri, headers, default_params, basic_auth, format), the content-type-aware Response, and the deterministic request building (query/body/header encoding, Basic auth, redirect following) HTTParty performs around the transport.
What it is — and isn't ¶
Everything HTTParty does *around* the wire is deterministic and needs no Ruby interpreter, so it lives here as pure Go: building the request URL (path resolved against base_uri, order-preserving escaped query strings), encoding the body (form or JSON), applying Basic auth, following 3xx redirects, and parsing the response by content type. The HTTP round-trip itself is a host seam: the Doer performs one transport request. The default production Doer is NetHTTP, backed by net/http; tests inject a DoerFunc stub and the core opens no socket itself. A future rbgo binding wires the real transport and maps Ruby's HTTParty surface onto this API.
Two entry points ¶
The package-level verb functions are the module methods:
resp, err := httparty.Get("https://api.example.com/users",
httparty.RequestOptions{Query: httparty.ParamsOf([2]string{"q", "ada"})})
if err != nil { /* an *httparty.Error */ }
_ = resp.Code() // 200
_ = resp.Success() // true for 2xx
v, _ := resp.Parsed() // JSON body -> map[string]any, XML -> map, else string
A Client models a class that does `include HTTParty` with its DSL:
api := httparty.NewClient(func(c *httparty.Client) {
c.BaseURI("https://api.example.com").
Headers(httparty.HeadersOf([2]string{"Accept", "application/json"})).
BasicAuth("user", "pass").
Format("json")
})
resp, err := api.Post("/widgets", httparty.RequestOptions{
Body: map[string]any{"name": "gadget"}, // JSON-encoded
})
Value model ¶
Query params and url-encoded bodies are carried as an ordered string→string Params; headers as a case-insensitive, multi-valued Headers. A request body is a raw string, a *Params (form), or any value (JSON). The Response exposes Code/Body/Headers/Success and the content-type-aware Response.Parsed. Errors are an Error tree matched with errors.Is against the Err* sentinels.
Index ¶
- Variables
- func BasicHeaderFrom(login, password string) string
- func BuildQuery(params *Params) string
- func Escape(s string) string
- func IsResponseError(err error) bool
- func Unescape(s string) string
- type BasicAuth
- type Client
- func (c *Client) Adapter(d Doer) *Client
- func (c *Client) BaseURI(uri string) *Client
- func (c *Client) BasicAuth(user, pass string) *Client
- func (c *Client) DefaultParams(p *Params) *Client
- func (c *Client) Delete(path string, opts ...RequestOptions) (*Response, error)
- func (c *Client) Format(f string) *Client
- func (c *Client) Get(path string, opts ...RequestOptions) (*Response, error)
- func (c *Client) Head(path string, opts ...RequestOptions) (*Response, error)
- func (c *Client) Headers(h *Headers) *Client
- func (c *Client) Options(path string, opts ...RequestOptions) (*Response, error)
- func (c *Client) Patch(path string, opts ...RequestOptions) (*Response, error)
- func (c *Client) Post(path string, opts ...RequestOptions) (*Response, error)
- func (c *Client) Put(path string, opts ...RequestOptions) (*Response, error)
- type Doer
- type DoerFunc
- type Error
- type ErrorKind
- type Headers
- func (h *Headers) Add(key, val string)
- func (h *Headers) Clone() *Headers
- func (h *Headers) Delete(key string)
- func (h *Headers) Get(key string) (string, bool)
- func (h *Headers) Has(key string) bool
- func (h *Headers) Len() int
- func (h *Headers) Merge(other *Headers) *Headers
- func (h *Headers) Pairs() []Pair
- func (h *Headers) Set(key, val string)
- func (h *Headers) SetDefault(key, val string)
- func (h *Headers) Values(key string) []string
- type NetHTTPDoer
- type Pair
- type Params
- func (p *Params) Clone() *Params
- func (p *Params) Delete(key string)
- func (p *Params) Encode() string
- func (p *Params) Get(key string) (string, bool)
- func (p *Params) Has(key string) bool
- func (p *Params) Len() int
- func (p *Params) Merge(other *Params) *Params
- func (p *Params) Pairs() []Pair
- func (p *Params) Set(key, val string)
- type RawResponse
- type Request
- type RequestOptions
- type Response
- func Delete(url string, opts ...RequestOptions) (*Response, error)
- func Get(url string, opts ...RequestOptions) (*Response, error)
- func Head(url string, opts ...RequestOptions) (*Response, error)
- func Options(url string, opts ...RequestOptions) (*Response, error)
- func Patch(url string, opts ...RequestOptions) (*Response, error)
- func Post(url string, opts ...RequestOptions) (*Response, error)
- func Put(url string, opts ...RequestOptions) (*Response, error)
Constants ¶
This section is empty.
Variables ¶
var ( ErrError = &Error{Kind: KindError, Message: string(KindError)} ErrUnsupportedFormat = &Error{Kind: KindUnsupportedFormat, Message: string(KindUnsupportedFormat)} ErrUnsupportedURIScheme = &Error{Kind: KindUnsupportedURIScheme, Message: string(KindUnsupportedURIScheme)} ErrResponseError = &Error{Kind: KindResponseError, Message: string(KindResponseError)} ErrRedirectionTooDeep = &Error{Kind: KindRedirectionTooDeep, Message: string(KindRedirectionTooDeep)} ErrDuplicateLocationHeader = &Error{Kind: KindDuplicateLocationHeader, Message: string(KindDuplicateLocationHeader)} )
Sentinel errors for errors.Is matching. Each names an HTTParty error kind; a concrete Error with that Kind (or a subtree of it) matches via Error.Is.
Functions ¶
func BasicHeaderFrom ¶
BasicHeaderFrom returns the HTTP Basic Authorization header value for a login and password: "Basic " followed by the newline-free base64 of "login:password", matching HTTParty's basic_auth handling.
func BuildQuery ¶
BuildQuery renders params as a query string: the params are emitted in insertion order (HTTParty preserves the Hash order rather than sorting) and each key and value is run through Escape.
func Escape ¶
Escape percent-encodes s exactly as Ruby's ERB::Util.url_encode does (the encoder HTTParty uses for query values): the unreserved set [A-Za-z0-9_.\-~] is left literal and every other byte — including a space — becomes %XX with upper-case hex.
func IsResponseError ¶
IsResponseError reports whether err is an HTTParty::ResponseError (or subclass).
Types ¶
type BasicAuth ¶
BasicAuth carries HTTP Basic credentials, mirroring HTTParty's :basic_auth => { username:, password: } option and the basic_auth class DSL.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a configured HTTParty client, modelling a Ruby class that does `include HTTParty` together with its class-level DSL: Client.BaseURI (base_uri), Client.Headers (headers), Client.DefaultParams (default_params), Client.BasicAuth (basic_auth) and Client.Format (format). Its verb methods (Client.Get, Client.Post, …) issue requests bound to that configuration. The package-level verb functions (Get, Post, …) are the module methods (HTTParty.get, …), backed by a zero-value client.
func NewClient ¶
NewClient builds a Client, optionally configured by a block (mirroring the class-level DSL applied when a class does `include HTTParty`).
func (*Client) Adapter ¶
Adapter sets the client's default transport Doer (the host seam); a per-call RequestOptions.Transport still overrides it. Tests inject a stub here or per call.
func (*Client) DefaultParams ¶
DefaultParams sets the default query params merged into every request (default_params).
func (*Client) Delete ¶
func (c *Client) Delete(path string, opts ...RequestOptions) (*Response, error)
Delete issues a DELETE request (HTTParty.delete).
func (*Client) Format ¶
Format forces the default response parse format (format): "json", "xml", "html", "csv" or "plain".
func (*Client) Get ¶
func (c *Client) Get(path string, opts ...RequestOptions) (*Response, error)
Get issues a GET request (HTTParty.get / .get on an including class).
func (*Client) Head ¶
func (c *Client) Head(path string, opts ...RequestOptions) (*Response, error)
Head issues a HEAD request (HTTParty.head).
func (*Client) Options ¶
func (c *Client) Options(path string, opts ...RequestOptions) (*Response, error)
Options issues an OPTIONS request (HTTParty.options).
func (*Client) Patch ¶
func (c *Client) Patch(path string, opts ...RequestOptions) (*Response, error)
Patch issues a PATCH request (HTTParty.patch).
type Doer ¶
type Doer interface {
Call(req *Request) (*RawResponse, error)
}
Doer is the transport host seam. Given a prepared Request, a Doer performs a single HTTP round-trip and returns the RawResponse, or an error. It never follows redirects — this package's client loop does that around the Doer — so the core is fully exercisable in tests against an in-process stub and opens no socket itself. The default production Doer is NetHTTP, backed by net/http; a host (rbgo) wires the real transport, and tests inject a DoerFunc.
type DoerFunc ¶
type DoerFunc func(req *Request) (*RawResponse, error)
DoerFunc adapts a function to the Doer interface — the convenient way to inject a stub transport in tests or a custom transport in a host.
type Error ¶
type Error struct {
// Kind names the specific HTTParty error subclass (see the Err* sentinels).
Kind ErrorKind
// Message is the error text (HTTParty::Error#message).
Message string
// Response is the response context for the ResponseError subtree
// (RedirectionTooDeep / DuplicateLocationHeader); nil otherwise.
Response *Response
// Cause is an underlying error, if any (e.g. a transport or JSON failure).
Cause error
}
Error is the root of HTTParty's error tree (HTTParty::Error < StandardError). The concrete kinds are distinguished by Error.Kind; the response-carrying errors (the HTTParty::ResponseError subtree) keep the Response that caused them. Match with errors.Is against the Err* sentinels, where a superclass matches its subclasses — mirroring Ruby's rescue of an HTTParty::Error subclass.
type ErrorKind ¶
type ErrorKind string
ErrorKind identifies an HTTParty error subclass.
const ( KindError ErrorKind = "HTTParty::Error" KindUnsupportedFormat ErrorKind = "HTTParty::UnsupportedFormat" KindUnsupportedURIScheme ErrorKind = "HTTParty::UnsupportedURIScheme" KindResponseError ErrorKind = "HTTParty::ResponseError" KindRedirectionTooDeep ErrorKind = "HTTParty::RedirectionTooDeep" KindDuplicateLocationHeader ErrorKind = "HTTParty::DuplicateLocationHeader" )
The HTTParty error subclasses, named as in the gem.
type Headers ¶
type Headers struct {
// contains filtered or unexported fields
}
Headers is a case-insensitive, insertion-ordered, multi-valued header map. A lookup matches keys case-insensitively while the original casing of the key is preserved for iteration and display. Multiple values for the same field are retained (like Net::HTTP's get_fields): Headers.Get joins them with ", " (the value HTTParty exposes via response.headers['field']) while Headers.Values returns them individually — which is how a duplicate Location header on a redirect is detected.
func HeadersOf ¶
HeadersOf builds a Headers from ordered key/value pairs (each via Headers.Set).
func (*Headers) Add ¶
Add appends another value for key without removing existing ones, mirroring a server sending the same header field twice.
func (*Headers) Delete ¶
Delete removes every entry for key (case-insensitive), keeping the order of the remaining headers.
func (*Headers) Get ¶
Get returns the ", "-joined values for key (case-insensitive) and whether the key was present, matching how HTTParty reads response.headers['field'].
func (*Headers) Merge ¶
Merge overlays other's headers onto a copy of h with Headers.Set semantics (each key in other replaces h's value for that key) and returns the result.
func (*Headers) Pairs ¶
Pairs returns the header entries in insertion order. The slice must not be mutated.
func (*Headers) Set ¶
Set assigns a single value to key: the first existing entry for key (case-insensitive) is updated in place and any further entries for key are dropped, so key ends up with exactly one value. A previously absent key is appended.
func (*Headers) SetDefault ¶
SetDefault assigns key→val only when key is absent (case-insensitive), so a caller-supplied value is never clobbered.
type NetHTTPDoer ¶
type NetHTTPDoer struct {
// Client performs the request; [NetHTTP] wires an http.Client that does not
// auto-follow redirects (this package follows them explicitly).
Client httpClient
}
NetHTTPDoer is the default Doer: it turns a Request into a net/http request, executes it with its Client, and maps the response (or a transport failure) back to a RawResponse. It models HTTParty's use of Net::HTTP.
func NetHTTP ¶
func NetHTTP() *NetHTTPDoer
NetHTTP returns the default net/http-backed Doer. Its http.Client is configured not to follow redirects itself ([noRedirect]) because redirect following is handled by the client loop around the Doer.
func (*NetHTTPDoer) Call ¶
func (d *NetHTTPDoer) Call(req *Request) (*RawResponse, error)
Call performs the HTTP round-trip for req with net/http.
type Params ¶
type Params struct {
// contains filtered or unexported fields
}
Params is an insertion-ordered string→string map used for query parameters (the :query option and the class-level default_params) and for url-encoded form bodies. Ruby's HTTParty threads plain Hashes through the request; this ordered map mirrors that, giving deterministic, order-preserving output for query strings (see BuildQuery).
func ParamsOf ¶
ParamsOf builds a Params from ordered key/value pairs (later duplicates overwrite earlier values, keeping the first position — Ruby Hash semantics).
func ParseQuery ¶
ParseQuery decodes an application/x-www-form-urlencoded query string into an ordered Params: each key and value is [Unescape]d, a bare key (no '=') maps to the empty string, an empty segment is skipped, and a later duplicate key overwrites an earlier one (keeping its position). A leading '?' is ignored.
func (*Params) Encode ¶
Encode renders the params as an order-preserving, escaped query string (see BuildQuery).
func (*Params) Merge ¶
Merge returns a new Params with p's entries first (in order), overlaid by other's (an existing key is overwritten in place, a new key is appended). This is how the class-level default_params merge with a per-request :query, matching HTTParty's default_params.merge(query).
type RawResponse ¶
type RawResponse struct {
// Code is the HTTP status code.
Code int
// Body is the raw response body as delivered by the transport.
Body string
// Headers are the response headers (repeats preserved via [Headers.Add]).
Headers *Headers
}
RawResponse is the wire response a Doer produces for a single round-trip: the status code, the raw (unparsed) body, and the response headers. HTTParty's content-type-aware parsing and redirect following happen in this package around the Doer, so a Doer performs exactly one request and never follows a redirect itself.
type Request ¶
type Request struct {
// Method is the upper-case HTTP method ("GET", "POST", …).
Method string
// URL is the fully-built request URL.
URL string
// Headers are the outgoing request headers.
Headers *Headers
// Body is the encoded request body (already form- or JSON-encoded, or a
// caller-supplied raw string; empty for bodiless requests).
Body string
// Options carries the per-call settings (see [RequestOptions]).
Options RequestOptions
}
Request is the prepared HTTP request handed to the transport Doer: the verb method, the fully-built URL (base_uri + path + query), the resolved headers and the encoded string body, plus the per-call RequestOptions a host transport may consult (e.g. Timeout). It models the state HTTParty::Request has assembled by the time it calls Net::HTTP.
type RequestOptions ¶
type RequestOptions struct {
// Query are the query-string parameters (the :query option), merged after
// the client's default_params.
Query *Params
// Body is the request body (the :body option): a raw string is sent as-is; a
// [*Params] is form-encoded (application/x-www-form-urlencoded); any other
// value is JSON-encoded (application/json).
Body any
// Headers are per-call request headers (the :headers option), merged over the
// client's default headers.
Headers *Headers
// BasicAuth sets HTTP Basic credentials (the :basic_auth option); it overrides
// the client's basic_auth for this call.
BasicAuth *BasicAuth
// Timeout is the request timeout in seconds (the :timeout option); metadata a
// host transport may honour (this package opens no socket itself).
Timeout int
// FollowRedirects controls 3xx following (the :follow_redirects option);
// nil means the HTTParty default of true.
FollowRedirects *bool
// MaxRedirects caps the redirect chain (the :limit option); <= 0 means the
// HTTParty default of 5.
MaxRedirects int
// Format forces the response parser (the :format option: "json", "xml",
// "html", "csv", "plain"); empty derives the format from the Content-Type.
Format string
// Transport injects the [Doer] for this call (the host seam); nil falls back
// to the client's transport, then to [NetHTTP]. Tests inject a stub here.
Transport Doer
}
RequestOptions is the per-call options bag, modelling the options Hash HTTParty accepts on every verb (HTTParty.get(url, query:, body:, headers:, basic_auth:, timeout:, follow_redirects:, format:)). The zero value is valid: an empty options set issues a plain request.
type Response ¶
type Response struct {
// contains filtered or unexported fields
}
Response models HTTParty::Response: the status code, the raw body, the response headers, and the content-type-aware Response.Parsed value. It is what every verb returns on a completed request.
func Delete ¶
func Delete(url string, opts ...RequestOptions) (*Response, error)
Delete issues a DELETE request, mirroring HTTParty.delete.
func Get ¶
func Get(url string, opts ...RequestOptions) (*Response, error)
Get issues a GET request with no base configuration, mirroring HTTParty.get.
func Head ¶
func Head(url string, opts ...RequestOptions) (*Response, error)
Head issues a HEAD request, mirroring HTTParty.head.
func Options ¶
func Options(url string, opts ...RequestOptions) (*Response, error)
Options issues an OPTIONS request, mirroring HTTParty.options.
func Patch ¶
func Patch(url string, opts ...RequestOptions) (*Response, error)
Patch issues a PATCH request, mirroring HTTParty.patch.
func Post ¶
func Post(url string, opts ...RequestOptions) (*Response, error)
Post issues a POST request, mirroring HTTParty.post.
func Put ¶
func Put(url string, opts ...RequestOptions) (*Response, error)
Put issues a PUT request, mirroring HTTParty.put.
func (*Response) Parsed ¶
Parsed returns the parsed body (HTTParty::Response#parsed_response): a JSON body becomes a map/slice/scalar, an XML body a nested map, and any other content type (html, csv, plain, unknown) the raw body string. The forced :format option overrides the Content-Type. A blank body yields the raw (blank) string. The result is computed once and cached. A malformed JSON/XML body returns a non-nil error, as HTTParty's parser raises.
