faraday

package module
v0.0.0-...-338275e Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 17, 2026 License: BSD-3-Clause Imports: 8 Imported by: 0

README

go-ruby-faraday/faraday

faraday — go-ruby-faraday

Docs License Go Coverage

A pure-Go (no cgo) reimplementation of the deterministic core of Ruby's faraday gem — the ubiquitous middleware-based HTTP client abstraction. It reproduces the connection builder, the request/response objects, the middleware stack (request + response middleware plus the adapter), and the URL / params / headers / body handling Faraday performs around a transport — without any Ruby runtime.

It is the Faraday client for go-embedded-ruby, but a standalone, reusable module — a sibling of go-ruby-oauth2, go-ruby-regexp and go-ruby-erb.

What it is — and isn't. Everything Faraday does around the wire is deterministic and needs no interpreter, so it lives here as pure Go: building the request URL, running the middleware stack (url-encoded and JSON body encoding, Basic / token authorization, JSON response parsing, status→error mapping, logging), and exposing the Response. The HTTP round-trip itself is a host seam: the terminal Doer (the adapter) performs the transport. The default production Doer is NetHTTP, backed by net/http; tests inject a DoerFunc stub and the core opens no socket itself. This mirrors the gem, whose adapter is the last middleware and the only piece that touches the network.

Features

Faithful port of the faraday gem's client core, validated against the gem on every platform where it is installed:

  • Connection builderfaraday.New(Options{URL, Headers, Params}) { |conn| … } with the block DSL conn.Request(...), conn.Response(...), conn.Adapter(...).
  • Verb methodsGet/Head/Delete/Trace/Options and Post/Put/Patch (with a body), each taking an optional per-request block (req.SetHeader, req.SetParam, req.SetBody, req.URL), plus the general RunRequest(method, url, body, headers, block).
  • Request / Response / EnvResponse.Status/Headers/Body/Success, Response.OnComplete, and the Env threaded through the stack.
  • Request middlewareurl_encoded (form-encode a *Params body), json (JSON-encode a value body), authorization (Bearer/Token …) and basic_auth (Basic base64(login:password)).
  • Response middlewarejson (parse a JSON body), raise_error (map a 4xx/5xx status to the matching Faraday::Error subclass), and logger.
  • Adapter seamconn.Adapter(Doer); NetHTTP() is the default net/http transport, a DoerFunc a test stub. The core never opens a socket.
  • Error treeFaraday::ErrorClientError (BadRequestError, UnauthorizedError, ForbiddenError, ResourceNotFound, ProxyAuthError, ConflictError, UnprocessableEntityError, TooManyRequestsError), ServerError, ConnectionFailed, TimeoutError, ParsingError, matched with errors.Is against the Err* sentinels (a superclass matches its subclasses).
  • UtilsBuildQuery/ParseQuery (sorted, +-for-space escaping), Escape/Unescape, BasicHeaderFrom, and case-insensitive Headers.

CGO-free, dependency-free (stdlib only), 100% test coverage, gofmt + go vet clean, and green across the six 64-bit Go targets (amd64, arm64, riscv64, loong64, ppc64le, s390x — big-endian).

Install

go get github.com/go-ruby-faraday/faraday

Usage

package main

import (
	"fmt"

	"github.com/go-ruby-faraday/faraday"
)

func main() {
	conn := faraday.New(faraday.Options{
		URL:     "https://api.example.com",
		Headers: faraday.HeadersOf([2]string{"Accept", "application/json"}),
	}, func(c *faraday.Connection) {
		c.Request("json")                          // encode a value body as JSON
		c.Request("authorization", "Bearer", "tok") // Authorization: Bearer tok
		c.Response("json")                         // parse a JSON response body
		c.Response("raise_error")                  // 4xx/5xx -> Faraday error
		c.Adapter(faraday.NetHTTP())               // transport seam (stub in tests)
	})

	resp, err := conn.Post("/widgets", map[string]any{"name": "gadget"},
		func(req *faraday.Request) { req.SetParam("verbose", "1") })
	if err != nil {
		// a *faraday.Error: use errors.Is(err, faraday.ErrResourceNotFound), etc.
		return
	}
	fmt.Println(resp.Status(), resp.Success(), resp.Body())
}
Injecting a transport (tests / hosts)
conn := faraday.New(faraday.Options{}, func(c *faraday.Connection) {
	c.Response("json")
	c.Adapter(faraday.DoerFunc(func(env *faraday.Env) error {
		env.Status = 200
		env.ResponseHeaders = faraday.HeadersOf([2]string{"Content-Type", "application/json"})
		env.ResponseBody = `{"ok":true}`
		return nil
	}))
})
resp, _ := conn.Get("/ping")
// resp.Body() == map[string]any{"ok": true}

Value model

gem this package
Faraday.new(url:, headers:, params:) New(Options{URL, Headers, Params}, block)
conn.get/post/... { |req| ... } conn.Get/Post/...(path, [body,] block)
conn.request :json / :url_encoded conn.Request("json") / ("url_encoded")
conn.request :authorization, 'Bearer', t conn.Request("authorization", "Bearer", t)
conn.response :json / :raise_error conn.Response("json") / ("raise_error")
conn.adapter :net_http conn.Adapter(NetHTTP()) (host seam)
Faraday::Response#status/body/success? (*Response).Status()/Body()/Success()
Faraday::Env *Env
Faraday::Error subtree *Error + Err* sentinels (errors.Is)
Faraday::Utils.build_query BuildQuery / ParseQuery / Escape

Tests & coverage

The suite pairs deterministic, ruby-free tests (which alone hold coverage at 100%, so the qemu cross-arch and Windows lanes pass the gate) with a differential oracle against the reference faraday gem: query building / parsing, escaping, url-encoded and JSON body encoding, and Basic-auth header construction are diffed byte-for-byte against the gem. The oracle scripts $stdout.binmode and skip themselves where the gem is absent. No test opens a socket — the transport adapter is stubbed everywhere.

COVERPKG=$(go list ./... | paste -sd, -)
go test -race -coverpkg="$COVERPKG" -coverprofile=cover.out ./...
go tool cover -func=cover.out | tail -1   # 100.0%

License

BSD-3-Clause — see LICENSE. Copyright the go-ruby-faraday/faraday authors.

WebAssembly

Being pure Go (CGO=0), this library also compiles to WebAssembly — both GOOS=js GOARCH=wasm (browser / Node.js) and GOOS=wasip1 GOARCH=wasm (WASI). CI builds both targets on every push, alongside the six 64-bit native/qemu arches.

GOOS=js     GOARCH=wasm go build ./...   # browser / Node
GOOS=wasip1 GOARCH=wasm go build ./...   # WASI (wasmtime, wasmer, wasmedge, …)

Documentation

Overview

Package faraday is a pure-Go (CGO-free) reimplementation of the deterministic core of Ruby's `faraday` gem — the ubiquitous middleware-based HTTP client abstraction: the connection builder, the request/response objects, the middleware stack (request and response middleware plus the adapter), and the URL/params/headers/body handling that Faraday performs around a transport.

What it is — and isn't

Everything Faraday does *around* the wire is deterministic and needs no interpreter, so it lives here as pure Go: building the request URL (path resolution against the base URL, order-preserving escaped query strings), running the request through the middleware stack (url-encoded and JSON body encoding, Basic and token authorization, JSON response parsing, status→error mapping, logging), and exposing the Response. The HTTP round-trip itself is a host seam: the terminal Doer (the adapter) performs the transport. The default production Doer is NetHTTP, backed by net/http; tests inject a DoerFunc stub, and the core opens no socket itself. This mirrors the gem, whose adapter is the last middleware and the only piece that touches the network.

Flow

conn := faraday.New(faraday.Options{
	URL:     "https://api.example.com",
	Headers: faraday.HeadersOf([2]string{"Accept", "application/json"}),
}, func(c *faraday.Connection) {
	c.Request("json")             // encode a struct/map body as JSON
	c.Request("authorization", "Bearer", "the-token")
	c.Response("json")            // parse a JSON response body
	c.Response("raise_error")     // map 4xx/5xx to a Faraday error
	c.Adapter(faraday.NetHTTP())  // transport seam (a stub in tests)
})

resp, err := conn.Post("/widgets", map[string]any{"name": "gadget"},
	func(req *faraday.Request) { req.SetParam("verbose", "1") })
if err != nil { /* a Faraday.Error: ResourceNotFound, ServerError, … */ }
_ = resp.Status()   // 201
_ = resp.Body()     // parsed JSON value
_ = resp.Success()  // true for 2xx

Value model

Query params and url-encoded bodies are carried as an ordered string→string Params; headers as a case-insensitive ordered Headers. A request body is an arbitrary value that the request middleware encode (a *Params for a form, any value for JSON) into the string the adapter sends. A host (go-embedded-ruby / rbgo) maps its Ruby Faraday::Connection / Request / Response / Env objects to and from these shapes.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrError               = &Error{Kind: KindError, Message: string(KindError)}
	ErrClientError         = &Error{Kind: KindClientError, Message: string(KindClientError)}
	ErrBadRequest          = &Error{Kind: KindBadRequest, Message: string(KindBadRequest)}
	ErrUnauthorized        = &Error{Kind: KindUnauthorized, Message: string(KindUnauthorized)}
	ErrForbidden           = &Error{Kind: KindForbidden, Message: string(KindForbidden)}
	ErrResourceNotFound    = &Error{Kind: KindResourceNotFound, Message: string(KindResourceNotFound)}
	ErrProxyAuth           = &Error{Kind: KindProxyAuth, Message: string(KindProxyAuth)}
	ErrConflict            = &Error{Kind: KindConflict, Message: string(KindConflict)}
	ErrUnprocessableEntity = &Error{Kind: KindUnprocessableEntity, Message: string(KindUnprocessableEntity)}
	ErrTooManyRequests     = &Error{Kind: KindTooManyRequests, Message: string(KindTooManyRequests)}
	ErrServerError         = &Error{Kind: KindServerError, Message: string(KindServerError)}
	ErrNilStatus           = &Error{Kind: KindNilStatus, Message: string(KindNilStatus)}
	ErrConnectionFailed    = &Error{Kind: KindConnectionFailed, Message: string(KindConnectionFailed)}
	ErrTimeout             = &Error{Kind: KindTimeout, Message: string(KindTimeout)}
	ErrSSL                 = &Error{Kind: KindSSL, Message: string(KindSSL)}
	ErrParsing             = &Error{Kind: KindParsing, Message: string(KindParsing)}
)

Sentinel errors for errors.Is matching. Each names a Faraday error kind; a concrete Error with that Kind (or a subtree of it) matches via Error.Is.

Functions

func BasicHeaderFrom

func BasicHeaderFrom(login, password string) string

BasicHeaderFrom returns the Basic Authorization header value for a login and password, mirroring Faraday::Utils.basic_header_from: "Basic " followed by the newline-free base64 of "login:password".

func BuildQuery

func BuildQuery(params *Params) string

BuildQuery renders params as an application/x-www-form-urlencoded query string, byte-faithful to Faraday::Utils.build_query: the params are emitted in insertion order (Faraday preserves the params' order rather than sorting) and each key and value is run through Escape.

func Escape

func Escape(s string) string

Escape percent-encodes s the way Faraday::Utils.escape does: the unreserved set [A-Za-z0-9 .\-_~] is left literal except that a space is rewritten to '+', and every other byte becomes %XX with upper-case hex.

func IsClientError

func IsClientError(err error) bool

IsClientError reports whether err is a Faraday 4xx client error (or subclass).

func IsServerError

func IsServerError(err error) bool

IsServerError reports whether err is a Faraday 5xx server error (or subclass).

func Unescape

func Unescape(s string) string

Unescape reverses Escape: '+' becomes a space and %XX becomes its byte. An invalid or truncated %XX is left literal, matching Faraday's tolerant decoder.

Types

type Builder

type Builder struct {
	// contains filtered or unexported fields
}

Builder is the middleware stack, mirroring Faraday::RackBuilder. It records the request and response middleware (in declaration order) and the terminal adapter, then composes them into a single Handler. Registration by symbolic name (request/response) matches Faraday's DSL; the typed constructors in middleware.go are the underlying implementations, also usable via Builder.Use.

func (*Builder) Use

func (b *Builder) Use(m Middleware)

Use appends an already-constructed Middleware to the stack, mirroring Faraday's `use`. Middleware run in declaration order (outermost first).

type Connection

type Connection struct {
	// contains filtered or unexported fields
}

Connection is a configured HTTP client bound to a base URL, default headers and params, and a middleware stack, mirroring Faraday::Connection. Build one with New; issue requests with the verb methods or Connection.RunRequest.

func New

func New(opts Options, block ...func(*Connection)) *Connection

New builds a Connection, mirroring Faraday.new(...) { |conn| ... }. The options seed the base URL, default headers and params; the optional block configures the middleware stack (conn.Request/Response/Adapter). If no adapter is set in the block, the connection defaults to the net/http adapter (NetHTTP) — tests override it with a stub via conn.Adapter.

func (*Connection) Adapter

func (c *Connection) Adapter(d Doer)

Adapter sets the terminal transport (the host seam), mirroring Faraday::Connection#adapter. Pass NetHTTP for the default net/http transport or any Doer (e.g. a DoerFunc stub in tests).

func (*Connection) BuildRequest

func (c *Connection) BuildRequest(method, path string, body any, headers *Headers, block func(*Request)) *Request

BuildRequest constructs the Request for a verb call: it seeds the request with clones of the connection's default headers and params, applies method, path, body and per-call headers, then runs the block, mirroring Faraday::Connection#build_request.

func (*Connection) BuildURL

func (c *Connection) BuildURL(path string, params *Params) string

BuildURL resolves path against the connection's base URL and appends the merged query params (base-URL query overlaid by the request params), mirroring Faraday::Connection#build_url. Params keep their order and are escaped by BuildQuery.

func (*Connection) Delete

func (c *Connection) Delete(path string, block ...func(*Request)) (*Response, error)

Delete issues a DELETE request (Faraday::Connection#delete).

func (*Connection) Get

func (c *Connection) Get(path string, block ...func(*Request)) (*Response, error)

Get issues a GET request for path (resolved against the base URL), optionally configured by a block (Faraday::Connection#get).

func (*Connection) Head

func (c *Connection) Head(path string, block ...func(*Request)) (*Response, error)

Head issues a HEAD request (Faraday::Connection#head).

func (*Connection) Headers

func (c *Connection) Headers() *Headers

Headers returns the connection's default headers (Faraday::Connection#headers).

func (*Connection) Options

func (c *Connection) Options(path string, block ...func(*Request)) (*Response, error)

Options issues an OPTIONS request (Faraday::Connection#options).

func (*Connection) Params

func (c *Connection) Params() *Params

Params returns the connection's default query params (Faraday::Connection#params).

func (*Connection) Patch

func (c *Connection) Patch(path string, body any, block ...func(*Request)) (*Response, error)

Patch issues a PATCH request with the given body (Faraday::Connection#patch).

func (*Connection) Post

func (c *Connection) Post(path string, body any, block ...func(*Request)) (*Response, error)

Post issues a POST request with the given body (Faraday::Connection#post).

func (*Connection) Put

func (c *Connection) Put(path string, body any, block ...func(*Request)) (*Response, error)

Put issues a PUT request with the given body (Faraday::Connection#put).

func (*Connection) Request

func (c *Connection) Request(name string, args ...string)

Request registers a request middleware by symbolic name, mirroring Faraday::Connection#request. See [Builder.request] for the supported names ("url_encoded", "json", "authorization" type+value, "basic_auth" login+pass).

func (*Connection) Response

func (c *Connection) Response(name string, w ...io.Writer)

Response registers a response middleware by symbolic name, mirroring Faraday::Connection#response. Supported names: "json", "raise_error", and "logger". For "logger", pass a destination writer (nil ⇒ os.Stderr).

func (*Connection) RunRequest

func (c *Connection) RunRequest(method, path string, body any, headers *Headers, block func(*Request)) (*Response, error)

RunRequest builds the request, assembles the Env, runs it through the middleware stack, and returns the finished Response, mirroring Faraday::Connection#run_request. A middleware (or the adapter) that aborts the stack is returned as the error, with a nil response.

func (*Connection) Trace

func (c *Connection) Trace(path string, block ...func(*Request)) (*Response, error)

Trace issues a TRACE request (Faraday::Connection#trace).

func (*Connection) URLPrefix

func (c *Connection) URLPrefix() string

URLPrefix returns the connection's base URL string (Faraday::Connection#url_prefix).

func (*Connection) Use

func (c *Connection) Use(m Middleware)

Use appends an already-constructed Middleware to the stack (Faraday::Connection#use).

type Doer

type Doer interface {
	Call(env *Env) error
}

Doer is the transport host seam, mirroring the role a Faraday::Adapter plays as the terminal middleware. Given a prepared Env (Method, URL, RequestHeaders, and a string RequestBody left by the request middleware), a Doer performs the HTTP round-trip and fills in the response half (Status, ResponseHeaders, ResponseBody, Reason), or returns an error.

The default production Doer is NetHTTP, backed by net/http. The core opens no socket itself: every request runs through whatever Doer the connection's adapter is set to, so tests inject a stub (see DoerFunc) and never touch the network.

type DoerFunc

type DoerFunc func(env *Env) error

DoerFunc adapts a function to the Doer interface, the convenient way to inject a stub adapter in tests or a custom transport in a host.

func (DoerFunc) Call

func (f DoerFunc) Call(env *Env) error

Call invokes f(env).

type Env

type Env struct {
	// Method is the upper-case HTTP method ("GET", "POST", …).
	Method string
	// URL is the fully-built request URL (path resolved against the connection's
	// url_prefix, with the merged query string appended).
	URL string
	// RequestHeaders are the outgoing headers.
	RequestHeaders *Headers
	// RequestBody is the outgoing body. It starts as whatever the caller set
	// (a [*Params] for a form, an arbitrary value for JSON, or a string) and is
	// rewritten to the encoded string by the request middleware.
	RequestBody any
	// Params are the request query parameters (already merged into URL; kept for
	// middleware that inspect them).
	Params *Params
	// Request carries the per-request options (see [RequestOptions]).
	Request RequestOptions

	// Status is the response status code, set by the adapter.
	Status int
	// ResponseHeaders are the response headers, set by the adapter.
	ResponseHeaders *Headers
	// ResponseBody is the response body: the raw string as delivered by the
	// adapter, rewritten to a parsed value by response middleware (e.g. JSON).
	ResponseBody any
	// Reason is the response reason phrase, when the adapter supplies one.
	Reason string
	// contains filtered or unexported fields
}

Env is the mutable state threaded through the middleware stack, mirroring Faraday::Env. Request middleware read and rewrite the request half (Method/URL/RequestHeaders/RequestBody/Params) on the way in; the adapter fills in the response half (Status/ResponseHeaders/ResponseBody/Reason); then response middleware read and rewrite it on the way out.

func (*Env) Success

func (e *Env) Success() bool

Success reports whether the env's status is a 2xx (Faraday::Env#success?).

type Error

type Error struct {
	// Kind names the specific Faraday error subclass (see the Err* sentinels).
	Kind ErrorKind
	// Message is the error text (Faraday::Error#message).
	Message string
	// Response is the response context when the error was raised from a response
	// (raise_error / a 4xx–5xx status); nil for transport errors.
	Response *Response
	// Cause is the underlying transport error, if any (ConnectionFailed /
	// TimeoutError wrap the adapter's error).
	Cause error
}

Error is the root of Faraday's error tree (Faraday::Error). Every Faraday error carries a human message and, for errors raised from a response by the raise_error middleware, the response context (Error.Response) so callers can inspect the status, headers and body that triggered it.

The concrete kinds are distinguished by Error.Kind; the standard predicate helpers (IsClientError, IsServerError, …) and the sentinel values (ErrClientError, …) let callers match with errors.Is, mirroring Ruby's rescue of a Faraday::Error subclass.

func (*Error) Error

func (e *Error) Error() string

Error implements the error interface (Faraday::Error#message).

func (*Error) Is

func (e *Error) Is(target error) bool

Is reports whether e matches target: true when target is a *Error whose Kind is e's Kind or an ancestor of it, so errors.Is(err, ErrClientError) matches any 4xx-specific Faraday error, and errors.Is(err, ErrError) matches every Faraday error — mirroring Ruby's rescue of a superclass.

func (*Error) Unwrap

func (e *Error) Unwrap() error

Unwrap exposes the underlying transport error for errors.Is/As on the cause.

type ErrorKind

type ErrorKind string

ErrorKind identifies a Faraday error subclass.

const (
	KindError               ErrorKind = "Faraday::Error"
	KindClientError         ErrorKind = "Faraday::ClientError"
	KindBadRequest          ErrorKind = "Faraday::BadRequestError"
	KindUnauthorized        ErrorKind = "Faraday::UnauthorizedError"
	KindForbidden           ErrorKind = "Faraday::ForbiddenError"
	KindResourceNotFound    ErrorKind = "Faraday::ResourceNotFound"
	KindProxyAuth           ErrorKind = "Faraday::ProxyAuthError"
	KindConflict            ErrorKind = "Faraday::ConflictError"
	KindUnprocessableEntity ErrorKind = "Faraday::UnprocessableEntityError"
	KindTooManyRequests     ErrorKind = "Faraday::TooManyRequestsError"
	KindServerError         ErrorKind = "Faraday::ServerError"
	KindNilStatus           ErrorKind = "Faraday::NilStatusError"
	KindConnectionFailed    ErrorKind = "Faraday::ConnectionFailed"
	KindTimeout             ErrorKind = "Faraday::TimeoutError"
	KindSSL                 ErrorKind = "Faraday::SSLError"
	KindParsing             ErrorKind = "Faraday::ParsingError"
)

The Faraday error subclasses, named as in the gem.

type Handler

type Handler func(env *Env) error

Handler is one step of the resolved middleware stack: it receives the Env, does its work (possibly calling the next handler), and returns an error to abort the stack. The terminal handler is the adapter.

type Headers

type Headers struct {
	// contains filtered or unexported fields
}

Headers is a case-insensitive, insertion-ordered header map, mirroring Faraday::Utils::Headers. A lookup matches keys case-insensitively while the original casing of the first-seen key is preserved for iteration and display (so "Content-Type" and "content-type" address the same entry).

func HeadersOf

func HeadersOf(kv ...[2]string) *Headers

HeadersOf builds a Headers from ordered key/value pairs.

func NewHeaders

func NewHeaders() *Headers

NewHeaders returns an empty Headers.

func (*Headers) Clone

func (h *Headers) Clone() *Headers

Clone returns a shallow copy of h.

func (*Headers) Delete

func (h *Headers) Delete(key string)

Delete removes key (case-insensitive) if present, keeping the order of the remaining headers.

func (*Headers) Get

func (h *Headers) Get(key string) (string, bool)

Get returns the value for key (case-insensitive) and whether it was present.

func (*Headers) Has

func (h *Headers) Has(key string) bool

Has reports whether key is present (case-insensitive).

func (*Headers) Len

func (h *Headers) Len() int

Len reports the number of headers.

func (*Headers) Merge

func (h *Headers) Merge(other *Headers) *Headers

Merge overlays other's headers onto a copy of h and returns the result (an existing key is overwritten in place, a new key is appended).

func (*Headers) Pairs

func (h *Headers) Pairs() []Pair

Pairs returns the headers in insertion order (with first-seen key casing). The slice must not be mutated.

func (*Headers) Set

func (h *Headers) Set(key, val string)

Set inserts or replaces the value for key (case-insensitive). An existing key keeps its original casing and position; only the value is updated.

func (*Headers) SetDefault

func (h *Headers) SetDefault(key, val string)

SetDefault inserts key→val only if key is absent (case-insensitive), matching middleware that fills in a header without clobbering a caller override.

type Middleware

type Middleware func(next Handler) Handler

Middleware wraps a downstream Handler and returns a new one, mirroring a Faraday::Middleware instance in the RackBuilder. The stack is composed outermost-first; a request middleware acts before calling next, a response middleware acts after next returns.

func Authorization

func Authorization(typ, value string) Middleware

Authorization is the request middleware Faraday::Request::Authorization for a scheme with a single token: it sets "Authorization: <typ> <value>" (e.g. "Bearer <token>", "Token <token>") unless the header is already present. For HTTP Basic use BasicAuth.

func BasicAuth

func BasicAuth(login, password string) Middleware

BasicAuth is the request middleware for HTTP Basic authentication (Faraday::Request::Authorization with the :basic scheme): it sets "Authorization: Basic base64(login:password)" unless already present.

func JSONRequest

func JSONRequest() Middleware

JSONRequest is the request middleware Faraday::Request::Json: when the request body is a non-string value and the content type is unset or JSON, it JSON-encodes the body and sets Content-Type: application/json. A body that is already a string (pre-encoded) is left untouched; a value that cannot be marshalled raises a Faraday error.

func JSONResponse

func JSONResponse() Middleware

JSONResponse is the response middleware Faraday::Response::Json: when the response Content-Type is a JSON media type and the body is a non-blank string, it parses the body and replaces env.ResponseBody with the decoded value (map/slice/scalar). A malformed JSON body raises a Faraday parsing error.

func Logger

func Logger(w io.Writer) Middleware

Logger is the response middleware Faraday::Response::Logger: it writes a line for the outgoing request and one for the completed response to w (os.Stderr when w is nil), leaving the request/response otherwise unchanged.

func RaiseError

func RaiseError() Middleware

RaiseError is the response middleware Faraday::Response::RaiseError: on completion it maps the response status to a Faraday error, so a 4xx/5xx response aborts the stack with the matching subclass. Specific codes get their named error (404 → ResourceNotFound, 422 → UnprocessableEntity, …); other 4xx map to ClientError and 5xx to ServerError. A 2xx/3xx status passes through.

func UrlEncoded

func UrlEncoded() Middleware

UrlEncoded is the request middleware Faraday::Request::UrlEncoded: when the request body is a *Params and the content type is unset or already form-encoded, it encodes the body to an application/x-www-form-urlencoded string and sets the Content-Type header. Any other body is left untouched.

type NetHTTPDoer

type NetHTTPDoer struct {
	// Client performs the request; defaults to http.DefaultClient.
	Client httpClient
}

NetHTTPDoer is the default Doer: it turns an Env into a net/http request, executes it with its Client, and maps the response (or a transport failure) back onto the env. It mirrors Faraday's net_http adapter, including the mapping of a timeout to a Faraday TimeoutError and any other transport failure to a ConnectionFailed error.

func NetHTTP

func NetHTTP() *NetHTTPDoer

NetHTTP returns the default net/http-backed Doer.

func (*NetHTTPDoer) Call

func (d *NetHTTPDoer) Call(env *Env) error

Call performs the HTTP round-trip for env with net/http.

type Options

type Options struct {
	// URL is the base URL (url_prefix) that request paths resolve against.
	URL string
	// Headers are default headers merged into every request.
	Headers *Headers
	// Params are default query params merged into every request.
	Params *Params
}

Options configures a new Connection, mirroring the keyword options of Faraday.new(url:, headers:, params:). Empty fields take Faraday's defaults.

type Pair

type Pair struct {
	Key string
	Val string
}

Pair is one entry of an ordered string-keyed map.

type Params

type Params struct {
	// contains filtered or unexported fields
}

Params is an insertion-ordered string→string map used for request query parameters and url-encoded bodies. Ruby's Faraday threads plain Hashes through the flow; this ordered map mirrors that, giving deterministic, order-preserving output for query strings (see BuildQuery).

func NewParams

func NewParams() *Params

NewParams returns an empty ordered Params.

func ParamsOf

func ParamsOf(kv ...[2]string) *Params

ParamsOf builds a Params from ordered key/value pairs (later duplicates overwrite earlier values, keeping the first position — Ruby Hash semantics).

func ParseQuery

func ParseQuery(query string) *Params

ParseQuery decodes an application/x-www-form-urlencoded query string into an ordered Params, mirroring Faraday::Utils.parse_query: 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) Clone

func (p *Params) Clone() *Params

Clone returns a shallow copy of p.

func (*Params) Delete

func (p *Params) Delete(key string)

Delete removes key if present, keeping the order of the remaining entries.

func (*Params) Encode

func (p *Params) Encode() string

Encode renders the params as an order-preserving, escaped query string (see BuildQuery).

func (*Params) Get

func (p *Params) Get(key string) (string, bool)

Get returns the value for key and whether it was present.

func (*Params) Has

func (p *Params) Has(key string) bool

Has reports whether key is present.

func (*Params) Len

func (p *Params) Len() int

Len reports the number of entries.

func (*Params) Merge

func (p *Params) Merge(other *Params) *Params

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 a connection's default params merge with a request's, matching Faraday::Connection#build_url's params.merge(request.params).

func (*Params) Pairs

func (p *Params) Pairs() []Pair

Pairs returns the entries in insertion order. The slice must not be mutated.

func (*Params) Set

func (p *Params) Set(key, val string)

Set inserts or replaces the entry for key, preserving the position of an existing key when it is overwritten (last write wins on value, first write wins on order — the gem's Hash semantics).

type Request

type Request struct {
	// Method is the upper-case HTTP method.
	Method string
	// Path is the request path or URL passed to the verb method; it is resolved
	// against the connection's url_prefix when the URL is built.
	Path string
	// Params are the request query parameters (seeded from the connection's
	// defaults; the block may add to or overwrite them).
	Params *Params
	// Headers are the request headers (seeded from the connection's defaults).
	Headers *Headers
	// Body is the request body (nil, a [*Params] for a form, an arbitrary value
	// for JSON, or a pre-encoded string).
	Body any
	// Options carries the per-request settings (timeouts, context).
	Options RequestOptions
}

Request is the mutable request the caller configures inside a per-request block, mirroring Faraday::Request. A verb method (Get/Post/…) yields a fresh Request pre-seeded with the connection's default headers and params; the block then tweaks its method, path, params, headers and body before the middleware stack runs.

func (*Request) SetBody

func (r *Request) SetBody(body any)

SetBody sets the request body (convenience for req.body = ...).

func (*Request) SetHeader

func (r *Request) SetHeader(key, val string)

SetHeader sets a request header (convenience for req.headers['K'] = v).

func (*Request) SetParam

func (r *Request) SetParam(key, val string)

SetParam sets a request query parameter (convenience for req.params['k'] = v).

func (*Request) URL

func (r *Request) URL(path string, params ...*Params)

URL sets the request path and, optionally, replaces its query params, matching Faraday::Request#url. Passing params overwrites the request's params.

type RequestOptions

type RequestOptions struct {
	// Timeout is the overall request timeout; 0 means unset.
	Timeout int
	// OpenTimeout is the connection-open timeout; 0 means unset.
	OpenTimeout int
	// Context is a free-form bag for middleware to stash per-request state,
	// mirroring env[:request][:context].
	Context map[string]any
}

RequestOptions carries the per-request settings Faraday keeps on env[:request]: connect/read timeouts and any middleware-specific context. The deterministic core does not open sockets, so the timeouts are metadata a host adapter may honour.

type Response

type Response struct {
	// contains filtered or unexported fields
}

Response is the result of running a request through the middleware stack, mirroring Faraday::Response. It is a thin, read-only view over the finished Env: Status, Headers and Body reflect the response half after every response middleware has run.

func (*Response) Body

func (r *Response) Body() any

Body returns the response body (Faraday::Response#body): the raw string, or the parsed value after a parsing middleware (e.g. JSON) has run.

func (*Response) Env

func (r *Response) Env() *Env

Env returns the underlying Env (Faraday::Response#env).

func (*Response) Finished

func (r *Response) Finished() bool

Finished reports whether the response has completed (Faraday::Response#finished?).

func (*Response) Headers

func (r *Response) Headers() *Headers

Headers returns the response headers (Faraday::Response#headers).

func (*Response) OnComplete

func (r *Response) OnComplete(cb func(*Response))

OnComplete registers a callback to run when the response finishes, mirroring Faraday::Response#on_complete. If the response has already finished, the callback runs immediately.

func (*Response) ReasonPhrase

func (r *Response) ReasonPhrase() string

ReasonPhrase returns the response reason phrase, if any (Faraday::Response#reason_phrase).

func (*Response) Status

func (r *Response) Status() int

Status returns the HTTP status code (Faraday::Response#status).

func (*Response) Success

func (r *Response) Success() bool

Success reports whether the status is a 2xx (Faraday::Response#success?).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL