Skip to main content

contentstack_api_client_rs/client/
delivery.rs

1pub mod entries;
2
3use reqwest::{
4    Client,
5    header::{HeaderMap, HeaderValue},
6};
7use reqwest_middleware::{ClientBuilder, ClientWithMiddleware};
8
9use crate::{
10    client::{
11        config::{ClientConfig, ClientOptions},
12        delivery::entries::Entries,
13    },
14    middleware::rate_limiter::RateLimiterMiddleware,
15    rate_limiter::{ClientRateLimiter, RateLimitPreset},
16};
17
18/// Async HTTP client for the Contentstack Content Delivery API (CDN).
19///
20/// Holds a connection pool and injects the required authentication headers
21/// on every request automatically.
22pub struct Delivery {
23    pub config: ClientConfig,
24    pub client: ClientWithMiddleware,
25}
26
27impl Delivery {
28    /// Creates a new `Delivery` client.
29    ///
30    /// # Arguments
31    ///
32    /// * `api_key` - Your stack's API key
33    /// * `delivery_token` - Environment-specific delivery token
34    /// * `environment` - The publishing environment (e.g. `"production"`)
35    /// * `opts` - Optional configuration overrides (region, timeout, max connections)
36    ///
37    /// # Example
38    ///
39    /// ```no_run
40    /// use contentstack_api_client_rs::Delivery;
41    ///
42    /// let client = Delivery::new("my_api_key", "my_delivery_token", "production", None);
43    /// ```
44    pub fn new(
45        api_key: &str,
46        delivery_token: &str,
47        environment: &str,
48        opts: Option<ClientOptions>,
49    ) -> Self {
50        let config = ClientConfig::delivery(api_key, delivery_token, environment, opts);
51        let mut headers = HeaderMap::new();
52
53        headers.insert(
54            "api_key",
55            HeaderValue::from_str(&config.api_key)
56                .expect("api_key contains invalid header characters"),
57        );
58
59        headers.insert(
60            "access_token",
61            HeaderValue::from_str(&config.delivery_token)
62                .expect("delivery_token contains invalid header characters"),
63        );
64
65        if let Some(ref env) = config.environment {
66            headers.insert(
67                "environment",
68                HeaderValue::from_str(env).expect("environment contains invalid header characters"),
69            );
70        }
71
72        let reqwest_client = Client::builder()
73            .default_headers(headers)
74            .timeout(config.timeout)
75            .pool_max_idle_per_host(config.max_connections)
76            .build()
77            .expect("Failed to build HTTP client");
78
79        let client = ClientBuilder::new(reqwest_client)
80            .with(RateLimiterMiddleware {
81                rate_limiter: ClientRateLimiter::new(RateLimitPreset::Delivery),
82            })
83            .build();
84
85        Self { config, client }
86    }
87
88    pub fn entries(&self) -> Entries<'_> {
89        Entries {
90            client: &self.client,
91            base_url: &self.config.base_url,
92        }
93    }
94}