pub async fn make_http_request<B: Serialize>(
client: &Client,
rate_limiter: &RateLimiter,
method: Method,
url: &str,
headers: Vec<(&str, &str)>,
body: &Option<B>,
retry_config: RetryConfig,
) -> Result<Response, AppError>Expand description
Makes an HTTP request with automatic rate limiting and retry on rate limit errors
This function provides a centralized way to make HTTP requests to the IG Markets API with built-in rate limiting and automatic retry logic.
§Arguments
client- The HTTP client to use for the requestrate_limiter- Shared rate limiter (borrowed) to pace the requestmethod- HTTP method (GET, POST, PUT, DELETE, etc.)url- Full URL to requestheaders- Vector of (header_name, header_value) tuplesbody- Optional request body (will be serialized to JSON)retry_config- Retry configuration (max retries and delay)
§Returns
Ok(Response)- Successful HTTP responseErr(AppError)- Error if request fails (excluding rate limit errors which are retried)
Retry is always finite: transient failures (429, 5xx, and IG allowance
rate limits) are retried with exponential backoff up to
retry_config.max_retries(); everything else fails fast. The 401
token-refresh path is handled by the caller, not here.
§Example
ⓘ
use ig_client::application::http::make_http_request;
use ig_client::model::retry::RetryConfig;
use reqwest::{Client, Method};
let client = Client::new();
let rate_limiter = RateLimiter::new(&config);
let headers = vec![
("X-IG-API-KEY", "your-api-key"),
("Content-Type", "application/json"),
];
// Finite defaults (DEFAULT_MAX_RETRIES retries, exponential backoff)
let response = make_http_request(
&client,
&rate_limiter,
Method::GET,
"https://demo-api.ig.com/gateway/deal/markets/EPIC",
headers.clone(),
&None::<()>,
RetryConfig::default(),
).await?;
// Maximum 3 retries with a 5 second base delay
let response = make_http_request(
&client,
&rate_limiter,
Method::GET,
"https://demo-api.ig.com/gateway/deal/markets/EPIC",
headers,
&None::<()>,
RetryConfig::with_max_retries_and_delay(3, 5),
).await?;