Skip to main content

HttpClient

Struct HttpClient 

Source
pub struct HttpClient {
    pub client: Client,
    pub base_url: Url,
    /* private fields */
}
Expand description

Shared HTTP client with base URL, optional rate limiter, and retry config.

This is the common structure used by all API clients to hold the configured reqwest client, base URL, and rate-limiting state.

Fields§

§client: Client

The underlying reqwest HTTP client

§base_url: Url

Base URL for API requests

Implementations§

Source§

impl HttpClient

Source

pub fn with_base_url(&self, base_url: &str) -> Result<Self, ApiError>

Clone this client, pointed at a different base URL.

The underlying reqwest client (and so its connection pool), rate limiter, retry config, and concurrency limiter are all shared with the original. Use this to reach a sibling API host that should share the same transport configuration and request budget — several Polymarket APIs live on their own subdomains but are consumed by one client.

Sharing the concurrency limiter is deliberate: the limit exists to keep Cloudflare from seeing a burst from this process, and that is a per-process concern rather than a per-host one.

§Path prefixes are ignored

Request paths are absolute (/user-pnl), and resolving an absolute path against a base replaces the base’s path entirely. So a prefix in base_url is silently dropped, with or without a trailing slash:

http://host          + /user-pnl -> http://host/user-pnl
http://host/proxy    + /user-pnl -> http://host/user-pnl   (prefix gone)
http://host/proxy/   + /user-pnl -> http://host/user-pnl   (prefix gone)

Point this at a scheme, host, and port — not at a sub-path. Fronting the API with a path-prefixed reverse proxy is not supported.

Source

pub async fn acquire_rate_limit(&self, path: &str, method: Option<&Method>)

Await rate limiter for the given endpoint path + method.

Source

pub async fn acquire_concurrency(&self) -> Option<OwnedSemaphorePermit>

Acquire a concurrency permit, if a limiter is configured.

The returned permit must be held until the HTTP response has been received. Dropping the permit releases the concurrency slot. Returns None when no concurrency limit is set.

Source

pub fn should_retry( &self, status: StatusCode, attempt: u32, retry_after: Option<&str>, ) -> Option<Duration>

Check if a response should be retried; returns backoff duration if yes.

Retries two statuses, both of which upstream documents as “retry with exponential backoff”:

  • 429 Too Many Requests — rate limited.
  • 425 Too Early — Polymarket’s matching engine is restarting. It returns this with no body, so nothing was processed.

Deliberately narrow: 5xx is not retried here. It is retriable in the ApiError::is_retriable sense, but a 5xx can mean the request was partially applied, and this loop resends non-idempotent writes. The two statuses above are safe because neither reaches the matching engine — and for order placement the resent body is byte-identical, so the order hash is unchanged and the venue rejects a genuine double-submit as a duplicate. Callers wanting broader retry semantics should drive them from ApiError::is_retriable with their own idempotency judgement.

When retry_after is Some, the server-provided delay is used instead of the client-computed exponential backoff (clamped to max_backoff_ms).

Source

pub async fn get_bytes( &self, path: &str, query: &[(String, String)], ) -> Result<Vec<u8>, ApiError>

GET a URL and return the raw response body as bytes.

Use this for endpoints that return non-JSON payloads (e.g. application/zip downloads). Applies the same rate-limiting, concurrency gating, and should_retry behavior as the JSON-oriented Request helper.

Non-2xx responses are mapped to ApiError via ApiError::from_response.

§Errors

Returns ApiError on URL-join failure, network errors, or non-2xx responses.

Trait Implementations§

Source§

impl Clone for HttpClient

Source§

fn clone(&self) -> HttpClient

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for HttpClient

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more