Skip to main content

contentstack_api_client_rs/client/delivery/
entries.rs

1use reqwest_middleware::ClientWithMiddleware;
2use serde::Deserialize;
3
4use crate::client::entries::{EntriesResponse, EntryResponse};
5use crate::client::params::{
6    GetManyParams, GetOneParams, SerializedGetManyParams, SerializedGetOneParams,
7};
8use crate::error::Result;
9
10pub use crate::client::entries::Entry;
11
12/// Sub-client for the Entries endpoint.
13///
14/// Obtained via [`crate::Delivery::entries`] - never constructed directly.
15pub struct Entries<'a> {
16    pub(super) client: &'a ClientWithMiddleware,
17    pub(super) base_url: &'a str,
18}
19
20impl<'a> Entries<'a> {
21    /// Builds the entries URL for a given content type, with an optional entry UID.
22    fn build_url(&self, content_type: &str, uid: Option<&str>) -> String {
23        let base_url = self.base_url.trim_end_matches('/');
24        match uid {
25            Some(u) => format!("{}/content_types/{}/entries/{}", base_url, content_type, u),
26            None => format!("{}/content_types/{}/entries", base_url, content_type),
27        }
28    }
29
30    /// Fetches multiple entries for a given content type.
31    ///
32    /// # Arguments
33    ///
34    /// * `content_type` - The content type UID (e.g. `"blog_post"`)
35    /// * `params` - Optional query parameters (filters, pagination, locale)
36    ///
37    /// # Example
38    ///
39    /// ```no_run
40    /// use serde::Deserialize;
41    /// use contentstack_api_client_rs::{Delivery, GetManyParams};
42    ///
43    /// #[derive(Deserialize)]
44    /// struct BlogPost { body: String }
45    ///
46    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
47    /// let client = Delivery::new("api_key", "token", "production", None);
48    /// let response = client.entries()
49    ///     .get_many::<BlogPost>("blog_post", None)
50    ///     .await?;
51    ///
52    /// println!("Total: {}", response.entries.len());
53    /// # Ok(())
54    /// # }
55    /// ```
56    pub async fn get_many<T>(
57        &self,
58        content_type: &str,
59        params: Option<GetManyParams>,
60    ) -> Result<EntriesResponse<T>>
61    where
62        T: for<'de> Deserialize<'de>,
63    {
64        let request = self.client.get(self.build_url(content_type, None));
65
66        let request = if let Some(p) = params {
67            let serialized: SerializedGetManyParams = p.into();
68            request.query(&serialized)
69        } else {
70            request
71        };
72
73        Ok(request.send().await?.json::<EntriesResponse<T>>().await?)
74    }
75
76    /// Fetches a single entry by UID for a given content type.
77    ///
78    /// # Arguments
79    ///
80    /// * `content_type` - The content type UID (e.g. `"blog_post"`)
81    /// * `uid` - The entry UID to fetch
82    /// * `params` - Optional query parameters (locale, query filter)
83    ///
84    /// # Example
85    ///
86    /// ```no_run
87    /// use serde::Deserialize;
88    /// use contentstack_api_client_rs::{Delivery, GetOneParams};
89    ///
90    /// #[derive(Deserialize)]
91    /// struct BlogPost { body: String }
92    ///
93    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
94    /// let client = Delivery::new("api_key", "token", "production", None);
95    /// let response = client.entries()
96    ///     .get_one::<BlogPost>("blog_post", "entry_uid_123", None)
97    ///     .await?;
98    ///
99    /// println!("Title: {}", response.entry.title);
100    /// # Ok(())
101    /// # }
102    /// ```
103    pub async fn get_one<T>(
104        &self,
105        content_type: &str,
106        uid: &str,
107        params: Option<GetOneParams>,
108    ) -> Result<EntryResponse<T>>
109    where
110        T: for<'de> Deserialize<'de>,
111    {
112        let request = self.client.get(self.build_url(content_type, Some(uid)));
113
114        let request = if let Some(p) = params {
115            let serialized: SerializedGetOneParams = p.into();
116            request.query(&serialized)
117        } else {
118            request
119        };
120
121        Ok(request.send().await?.json::<EntryResponse<T>>().await?)
122    }
123}