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.
22#[derive(Clone, Debug)]
23pub struct Delivery {
24    pub config: ClientConfig,
25    pub client: ClientWithMiddleware,
26}
27
28impl Delivery {
29    /// Creates a new `Delivery` client.
30    ///
31    /// # Arguments
32    ///
33    /// * `api_key` - Your stack's API key
34    /// * `delivery_token` - Environment-specific delivery token
35    /// * `environment` - The publishing environment (e.g. `"production"`)
36    /// * `opts` - Optional configuration overrides (region, timeout, max connections)
37    ///
38    /// # Example
39    ///
40    /// ```no_run
41    /// use contentstack_api_client_rs::Delivery;
42    ///
43    /// let client = Delivery::new("my_api_key", "my_delivery_token", "production", None);
44    /// ```
45    pub fn new(
46        api_key: &str,
47        delivery_token: &str,
48        environment: &str,
49        opts: Option<ClientOptions>,
50    ) -> Self {
51        let config = ClientConfig::delivery(api_key, delivery_token, environment, opts);
52        let mut headers = HeaderMap::new();
53
54        headers.insert(
55            "api_key",
56            HeaderValue::from_str(&config.api_key)
57                .expect("api_key contains invalid header characters"),
58        );
59
60        headers.insert(
61            "access_token",
62            HeaderValue::from_str(&config.delivery_token)
63                .expect("delivery_token contains invalid header characters"),
64        );
65
66        if let Some(ref env) = config.environment {
67            headers.insert(
68                "environment",
69                HeaderValue::from_str(env).expect("environment contains invalid header characters"),
70            );
71        }
72
73        let reqwest_client = Client::builder()
74            .default_headers(headers)
75            .timeout(config.timeout)
76            .pool_max_idle_per_host(config.max_connections)
77            .build()
78            .expect("Failed to build HTTP client");
79
80        let client = ClientBuilder::new(reqwest_client)
81            .with(RateLimiterMiddleware {
82                rate_limiter: ClientRateLimiter::new(RateLimitPreset::Delivery),
83            })
84            .build();
85
86        Self { config, client }
87    }
88
89    pub fn entries(&self) -> Entries<'_> {
90        Entries {
91            client: &self.client,
92            base_url: &self.config.base_url,
93        }
94    }
95}