The single HTTP chokepoint.
This is the only module in the library that talks to Req. Auth, every
resource module, and the session layer all route through it, which keeps
request building, error mapping, and telemetry in exactly one place — the
seam that makes offline testing and API-drift handling tractable.
Telemetry
Every request emits a :telemetry span:
[:picnic, :request, :start]— measurements::system_time; metadata::method,:path[:picnic, :request, :stop]— measurements::duration; metadata adds:statusand, on failure,:error(the error category)[:picnic, :request, :exception]— if the request raised
Summary
Functions
Like request/4 but returns the full Req.Response on success, for the
rare caller that needs response headers (login reads the auth token from
the x-picnic-auth header).
Executes a request and returns the decoded body.
Like raw_request/4 but hands back the response for any HTTP status,
leaving classification to the caller; only transport and decoding failures
become errors.
Maps a non-success response onto the matching Picnic.Error category. Pairs
with response/4 for callers that classify a response themselves.
Types
@type method() :: :get | :post | :put | :patch | :delete
@type result() :: {:ok, term()} | {:error, Picnic.Error.t()}
Functions
@spec raw_request(Picnic.Client.t(), method(), String.t(), keyword()) :: {:ok, Req.Response.t()} | {:error, Picnic.Error.t()}
Like request/4 but returns the full Req.Response on success, for the
rare caller that needs response headers (login reads the auth token from
the x-picnic-auth header).
@spec request(Picnic.Client.t(), method(), String.t(), keyword()) :: result()
Executes a request and returns the decoded body.
opts is passed to Req after :method and :url are set, so anything
Req.request/1 accepts works here — most usefully :json for a request
body and :params for query parameters.
Success is {:ok, body} where body is the decoded JSON (a map or list),
or nil for an empty body. All failures map onto Picnic.Error categories;
see that module.
@spec response(Picnic.Client.t(), method(), String.t(), keyword()) :: {:ok, Req.Response.t()} | {:error, Picnic.Error.t()}
Like raw_request/4 but hands back the response for any HTTP status,
leaving classification to the caller; only transport and decoding failures
become errors.
Login needs this: Picnic can signal "second factor required" with a
non-success status while still returning the provisional token in the
x-picnic-auth header, and that token is unrecoverable once the response has
been reduced to an error. Classify what you get back with status_error/1.
@spec status_error(Req.Response.t()) :: Picnic.Error.t()
Maps a non-success response onto the matching Picnic.Error category. Pairs
with response/4 for callers that classify a response themselves.