pub struct RestClient { /* private fields */ }Expand description
An authenticated HTTP client for one Alpaca endpoint.
Implementations§
Source§impl RestClient
impl RestClient
Sourcepub fn new(credentials: &Credentials, config: RestConfig) -> Result<Self>
pub fn new(credentials: &Credentials, config: RestConfig) -> Result<Self>
Builds a client from credentials and configuration.
Redirects are disabled deliberately. Because the base URL is overridable,
an http:// endpoint that redirects to https:// would replay a POST body
— and its auth headers — over cleartext, so the request must fail loudly
instead. The one route that legitimately redirects, the broker document
download, uses its own client.
§Errors
Returns Error::Credentials if the credentials cannot be encoded as
headers, or Error::Transport if the underlying HTTP client fails to build.
Sourcepub fn unauthenticated(config: RestConfig) -> Result<Self>
pub fn unauthenticated(config: RestConfig) -> Result<Self>
Builds a client that sends no authentication headers.
Alpaca’s crypto market data endpoints serve unauthenticated requests. Every other endpoint requires credentials.
§Errors
Returns Error::Transport if the underlying HTTP client fails to build.
Sourcepub fn config(&self) -> &RestConfig
pub fn config(&self) -> &RestConfig
The configuration this client was built with.
Sourcepub fn at_version(&self, api_version: &str) -> Self
pub fn at_version(&self, api_version: &str) -> Self
The same client, targeting a different API version segment.
Alpaca versions routes individually rather than per API, and it is not
unusual for a client’s own version to be wrong for a given route: the
trading API is v2 but its locate routes are v1 and its per-market
calendar is v3; the broker API is v1 but funding wallets are
v1beta and logos v1beta1.
Writing that at the call site is deliberate. A version buried in a client constructor is the mistake that shipped three event streams pointing at routes Alpaca had retired; this way the version sits next to the path it belongs to.
Cheap: the underlying HTTP client is shared, not rebuilt.
Sourcepub async fn get<T, Q>(&self, path: &str, query: &Q) -> Result<T>
pub async fn get<T, Q>(&self, path: &str, query: &Q) -> Result<T>
Issues a GET, sending query as URL parameters.
§Errors
Propagates transport, API, and decoding failures.
Sourcepub async fn delete<T, Q>(&self, path: &str, query: &Q) -> Result<T>
pub async fn delete<T, Q>(&self, path: &str, query: &Q) -> Result<T>
Issues a DELETE, sending query as URL parameters.
DELETE parameters go in the query string, not the body — which is what
the endpoints taking them (cancel_orders, close_position) expect.
§Errors
Propagates transport, API, and decoding failures.
Sourcepub async fn delete_effectful<T, Q>(&self, path: &str, query: &Q) -> Result<T>
pub async fn delete_effectful<T, Q>(&self, path: &str, query: &Q) -> Result<T>
Issues a DELETE that must never be replayed.
For the routes whose verb says “remove a record” and whose effect is
“submit an order”: DELETE /v2/positions/{asset} and
DELETE /v2/positions, plus their broker twins. HTTP calls a DELETE
idempotent and for those four it is not — a replayed liquidation sells
the same quantity twice. A timeout on one is reported, not retried; a 429
still is, because the rate limiter refused it before anything acted.
§Errors
Propagates transport, API, and decoding failures.
Sourcepub async fn request<T, Q, B>(
&self,
method: Method,
replay: Replay,
path: &str,
query: Option<&Q>,
body: Option<&B>,
) -> Result<T>
pub async fn request<T, Q, B>( &self, method: Method, replay: Replay, path: &str, query: Option<&Q>, body: Option<&B>, ) -> Result<T>
Issues a request with both a query string and a body.
replay decides what happens on a retryable status. Replay::ByMethod
is right for almost everything; pass Replay::Never for a route whose
effect contradicts its verb — one that submits an order or moves money
behind a PUT or a DELETE.
The six methods above cover routes that take one or the other, which is
nearly all of them. A handful take both — PUT /v2/watchlists:by_name
names the watchlist in the query and carries the update in the body —
and folding the query into the path string would skip its encoding.
§Errors
Propagates transport, API, and decoding failures.
Sourcepub async fn get_bytes<Q>(&self, path: &str, query: &Q) -> Result<Vec<u8>>
pub async fn get_bytes<Q>(&self, path: &str, query: &Q) -> Result<Vec<u8>>
Issues a GET and returns the response body as bytes.
For the routes that answer with something other than JSON. The logo
endpoint is the only one in this crate: it serves image/png, and
putting it through RestClient::get would try to parse a PNG as JSON.
§Errors
Propagates transport and API failures.
Sourcepub async fn request_raw<Q, B>(
&self,
method: Method,
replay: Replay,
path: &str,
query: Option<&Q>,
body: Option<&B>,
) -> Result<String>
pub async fn request_raw<Q, B>( &self, method: Method, replay: Replay, path: &str, query: Option<&Q>, body: Option<&B>, ) -> Result<String>
Issues a request and returns the raw response body without deserializing.
This is the escape hatch for a route this crate does not wrap, which
makes replay load-bearing: the wrapped routes have their answer chosen
for them, and here it is yours. Replay::Never for anything that acts
— a replayed liquidation sells twice.
§Errors
Propagates transport and API failures.
Trait Implementations§
Source§impl Clone for RestClient
impl Clone for RestClient
Auto Trait Implementations§
impl !RefUnwindSafe for RestClient
impl !UnwindSafe for RestClient
impl Freeze for RestClient
impl Send for RestClient
impl Sync for RestClient
impl Unpin for RestClient
impl UnsafeUnpin for RestClient
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more