Skip to main content

aws_lite_rs/api/
apigateway.rs

1//! Amazon API Gateway API client.
2//!
3//! Thin wrapper over generated ops. All URL construction and HTTP methods
4//! are in `ops::apigateway::ApigatewayOps`. This layer adds:
5//! - Ergonomic method signatures
6
7use crate::{
8    AwsHttpClient, Result,
9    ops::apigateway::ApigatewayOps,
10    types::apigateway::{RestApis, Stage, Stages, UpdateStageRequest},
11};
12
13/// Client for the Amazon API Gateway API
14pub struct ApigatewayClient<'a> {
15    ops: ApigatewayOps<'a>,
16}
17
18impl<'a> ApigatewayClient<'a> {
19    /// Create a new Amazon API Gateway API client
20    pub(crate) fn new(client: &'a AwsHttpClient) -> Self {
21        Self {
22            ops: ApigatewayOps::new(client),
23        }
24    }
25
26    /// Lists the RestApis resources for your collection.
27    pub async fn get_rest_apis(&self, position: &str, limit: &str) -> Result<RestApis> {
28        self.ops.get_rest_apis(position, limit).await
29    }
30
31    /// Gets information about one or more Stage resources.
32    pub async fn get_stages(&self, restapi_id: &str, deployment_id: &str) -> Result<Stages> {
33        self.ops.get_stages(restapi_id, deployment_id).await
34    }
35
36    /// Changes information about a Stage resource.
37    pub async fn update_stage(
38        &self,
39        restapi_id: &str,
40        stage_name: &str,
41        body: &UpdateStageRequest,
42    ) -> Result<Stage> {
43        self.ops.update_stage(restapi_id, stage_name, body).await
44    }
45}
46
47#[cfg(test)]
48mod tests {
49    use super::*;
50    use crate::MockClient;
51    use crate::types::apigateway::*;
52
53    // RestApis response uses "item" key (locationName) not "items" (memberName)
54    // This was verified via integration testing against the real API.
55
56    #[tokio::test]
57    async fn test_get_rest_apis_deserializes_item_key() {
58        let mut mock = MockClient::new();
59        mock.expect_get("/restapis")
60            .returning_json(serde_json::json!({
61                "item": [
62                    {"id": "abc123", "name": "my-api", "description": "A test API"}
63                ]
64            }));
65
66        let client = AwsHttpClient::from_mock(mock);
67        let result = client.apigateway().get_rest_apis("", "").await.unwrap();
68
69        assert_eq!(result.items.len(), 1);
70        let api = &result.items[0];
71        assert_eq!(api.id.as_deref(), Some("abc123"));
72        assert_eq!(api.name.as_deref(), Some("my-api"));
73        assert_eq!(api.description.as_deref(), Some("A test API"));
74    }
75
76    #[tokio::test]
77    async fn test_get_rest_apis_returns_empty_when_no_apis() {
78        let mut mock = MockClient::new();
79        mock.expect_get("/restapis")
80            .returning_json(serde_json::json!({}));
81
82        let client = AwsHttpClient::from_mock(mock);
83        let result = client.apigateway().get_rest_apis("", "").await.unwrap();
84
85        assert_eq!(result.items.len(), 0);
86        assert!(result.position.is_none());
87    }
88
89    #[tokio::test]
90    async fn test_get_stages_returns_stage_fields() {
91        let mut mock = MockClient::new();
92        mock.expect_get("/restapis/api-id-123/stages")
93            .returning_json(serde_json::json!({
94                "item": [
95                    {
96                        "stageName": "prod",
97                        "deploymentId": "deploy-abc",
98                        "cacheClusterEnabled": false,
99                        "tracingEnabled": true
100                    }
101                ]
102            }));
103
104        let client = AwsHttpClient::from_mock(mock);
105        let result = client
106            .apigateway()
107            .get_stages("api-id-123", "")
108            .await
109            .unwrap();
110
111        assert_eq!(result.item.len(), 1);
112        let stage = &result.item[0];
113        assert_eq!(stage.stage_name.as_deref(), Some("prod"));
114        assert_eq!(stage.deployment_id.as_deref(), Some("deploy-abc"));
115        assert_eq!(stage.cache_cluster_enabled, Some(false));
116        assert_eq!(stage.tracing_enabled, Some(true));
117    }
118
119    #[tokio::test]
120    async fn test_update_stage_returns_updated_fields() {
121        let mut mock = MockClient::new();
122        mock.expect_patch("/restapis/api-id-123/stages/prod")
123            .returning_json(serde_json::json!({
124                "stageName": "prod",
125                "deploymentId": "deploy-abc",
126                "cacheClusterEnabled": false,
127                "tracingEnabled": true
128            }));
129
130        let client = AwsHttpClient::from_mock(mock);
131        let result = client
132            .apigateway()
133            .update_stage(
134                "api-id-123",
135                "prod",
136                &UpdateStageRequest {
137                    rest_api_id: "api-id-123".to_string(),
138                    stage_name: "prod".to_string(),
139                    patch_operations: vec![PatchOperation {
140                        op: Some("replace".to_string()),
141                        path: Some("/tracingEnabled".to_string()),
142                        value: Some("true".to_string()),
143                        ..Default::default()
144                    }],
145                },
146            )
147            .await
148            .unwrap();
149
150        assert_eq!(result.stage_name.as_deref(), Some("prod"));
151        assert_eq!(result.tracing_enabled, Some(true));
152        assert_eq!(result.cache_cluster_enabled, Some(false));
153    }
154}