1use crate::{
2 Error,
3 cdk::mgmt::{HttpHeader, HttpMethod, HttpRequestArgs, http_request},
4 model::metrics::{HttpMetrics, SystemMetricKind, SystemMetrics},
5};
6use num_traits::ToPrimitive;
7use serde::de::DeserializeOwned;
8
9const MAX_RESPONSE_BYTES: u64 = 200_000;
10
11pub async fn http_get<T: DeserializeOwned>(
15 url: &str,
16 headers: &[(String, String)],
17) -> Result<T, Error> {
18 SystemMetrics::increment(SystemMetricKind::HttpOutcall);
20 HttpMetrics::increment("GET", url);
21
22 let headers: Vec<HttpHeader> = headers
23 .iter()
24 .map(|(name, value)| HttpHeader {
25 name: name.clone(),
26 value: value.clone(),
27 })
28 .collect();
29
30 let args = HttpRequestArgs {
31 url: url.to_string(),
32 method: HttpMethod::GET,
33 headers,
34 max_response_bytes: Some(MAX_RESPONSE_BYTES),
35 ..Default::default()
36 };
37
38 let res = http_request(&args)
39 .await
40 .map_err(|e| Error::HttpRequest(e.to_string()))?;
41
42 let status: u32 = res.status.0.to_u32().unwrap_or(0);
44 if status != 200 {
45 return Err(Error::HttpErrorCode(status));
46 }
47
48 let res: T = serde_json::from_slice::<T>(&res.body)?;
50
51 Ok(res)
52}