Skip to main content

busbar_sf_rest/client/
composite.rs

1use tracing::instrument;
2
3use busbar_sf_client::security::soql;
4
5use crate::composite::{
6    CompositeBatchRequest, CompositeBatchResponse, CompositeGraphRequest, CompositeGraphResponse,
7    CompositeRequest, CompositeResponse, CompositeTreeRequest, CompositeTreeResponse,
8};
9use crate::error::{Error, ErrorKind, Result};
10
11impl super::SalesforceRestClient {
12    /// Execute a composite request with multiple subrequests.
13    ///
14    /// The composite API allows up to 25 subrequests in a single API call.
15    /// Subrequests can reference results from earlier subrequests using `@{referenceId}`.
16    ///
17    /// Available since API v34.0.
18    #[instrument(skip(self, request))]
19    pub async fn composite(&self, request: &CompositeRequest) -> Result<CompositeResponse> {
20        self.client
21            .rest_post("composite", request)
22            .await
23            .map_err(Into::into)
24    }
25
26    /// Execute a composite batch request with multiple independent subrequests.
27    ///
28    /// The composite batch API executes up to 25 subrequests independently.
29    /// Unlike the standard composite API, subrequests cannot reference each other's results.
30    ///
31    /// Available since API v34.0.
32    #[instrument(skip(self, request))]
33    pub async fn composite_batch(
34        &self,
35        request: &CompositeBatchRequest,
36    ) -> Result<CompositeBatchResponse> {
37        self.client
38            .rest_post("composite/batch", request)
39            .await
40            .map_err(Into::into)
41    }
42
43    /// Execute a composite tree request to create record hierarchies.
44    ///
45    /// Creates parent records with nested child records in a single request.
46    /// Supports up to 200 records total across all levels of the hierarchy.
47    ///
48    /// Available since API v42.0.
49    ///
50    /// # Arguments
51    /// * `sobject` - The parent SObject type (e.g., "Account")
52    /// * `request` - The tree request containing parent records and nested children
53    #[instrument(skip(self, request))]
54    pub async fn composite_tree(
55        &self,
56        sobject: &str,
57        request: &CompositeTreeRequest,
58    ) -> Result<CompositeTreeResponse> {
59        if !soql::is_safe_sobject_name(sobject) {
60            return Err(Error::new(ErrorKind::Salesforce {
61                error_code: "INVALID_SOBJECT".to_string(),
62                message: "Invalid SObject name".to_string(),
63            }));
64        }
65        let path = format!("composite/tree/{}", sobject);
66        self.client
67            .rest_post(&path, request)
68            .await
69            .map_err(Into::into)
70    }
71
72    /// Execute a composite graph request with multiple independent graphs.
73    ///
74    /// Each graph contains a set of composite subrequests that can reference
75    /// each other within the same graph. Different graphs are independent.
76    ///
77    /// Available since API v50.0.
78    #[instrument(skip(self, request))]
79    pub async fn composite_graph(
80        &self,
81        request: &CompositeGraphRequest,
82    ) -> Result<CompositeGraphResponse> {
83        self.client
84            .rest_post("composite/graph", request)
85            .await
86            .map_err(Into::into)
87    }
88}