03_service_layer_intro/
03_service_layer_intro.rs1use std::sync::{Arc, RwLock};
13use wami::provider::AwsProvider;
14use wami::service::{GroupService, RoleService, UserService};
15use wami::store::memory::InMemoryWamiStore;
16use wami::wami::identity::group::requests::CreateGroupRequest;
17use wami::wami::identity::role::requests::CreateRoleRequest;
18use wami::wami::identity::user::requests::{CreateUserRequest, ListUsersRequest};
19
20#[tokio::main]
21async fn main() -> Result<(), Box<dyn std::error::Error>> {
22 println!("=== Service Layer Introduction ===\n");
23
24 println!("Step 1: Initializing services...\n");
26 let store = Arc::new(RwLock::new(InMemoryWamiStore::default()));
27 let _provider = Arc::new(AwsProvider::new());
28 let account_id = "123456789012";
29
30 let user_service = UserService::new(store.clone(), account_id.to_string());
32 let group_service = GroupService::new(store.clone(), account_id.to_string());
33 let role_service = RoleService::new(store.clone(), account_id.to_string());
34
35 println!("✓ Services initialized");
36
37 println!("\nStep 2: Creating resources via services...\n");
39
40 println!("Creating users...");
42 let alice_req = CreateUserRequest {
43 user_name: "alice".to_string(),
44 path: Some("/users/".to_string()),
45 permissions_boundary: None,
46 tags: None,
47 };
48 let alice = user_service.create_user(alice_req).await?;
49 println!("✓ Created user: {}", alice.user_name);
50
51 let bob_req = CreateUserRequest {
52 user_name: "bob".to_string(),
53 path: Some("/users/".to_string()),
54 permissions_boundary: None,
55 tags: None,
56 };
57 user_service.create_user(bob_req).await?;
58 println!("✓ Created user: bob");
59
60 println!("\nCreating groups...");
62 let dev_group_req = CreateGroupRequest {
63 group_name: "developers".to_string(),
64 path: Some("/groups/".to_string()),
65 tags: None,
66 };
67 let dev_group = group_service.create_group(dev_group_req).await?;
68 println!("✓ Created group: {}", dev_group.group_name);
69
70 println!("\nCreating role...");
72 let role_req = CreateRoleRequest {
73 role_name: "deploy-role".to_string(),
74 path: Some("/roles/".to_string()),
75 assume_role_policy_document: r#"{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"*"},"Action":"sts:AssumeRole"}]}"#.to_string(),
76 description: Some("Role for deployment".to_string()),
77 max_session_duration: Some(3600),
78 permissions_boundary: None,
79 tags: None,
80 };
81 let role = role_service.create_role(role_req).await?;
82 println!("✓ Created role: {}", role.role_name);
83
84 println!("\n\nStep 3: Reading resources via services...\n");
86
87 let alice_retrieved = user_service.get_user("alice").await?;
89 if let Some(user) = alice_retrieved {
90 println!("✓ Retrieved user 'alice':");
91 println!(" - User ID: {}", user.user_id);
92 println!(" - ARN: {}", user.arn);
93 }
94
95 let users = user_service
97 .list_users(ListUsersRequest {
98 path_prefix: None,
99 pagination: None,
100 })
101 .await?;
102 println!("\n✓ Found {} users via service:", users.0.len());
103 for user in &users.0 {
104 println!(" - {}", user.user_name);
105 }
106
107 println!("\n\nStep 4: Updating resources via services...\n");
109
110 use wami::wami::identity::user::requests::UpdateUserRequest;
111 let update_req = UpdateUserRequest {
112 user_name: "alice".to_string(),
113 new_user_name: None,
114 new_path: Some("/admin-users/".to_string()),
115 };
116 user_service.update_user(update_req).await?;
117 println!("✓ Updated alice's path to '/admin-users/'");
118
119 println!("\n\nStep 5: Deleting resources via services...\n");
121
122 user_service.delete_user("bob").await?;
123 println!("✓ Deleted user 'bob'");
124
125 let bob_check = user_service.get_user("bob").await?;
127 if bob_check.is_none() {
128 println!(" Verified: bob no longer exists");
129 }
130
131 println!("\n✅ Example completed successfully!");
132 println!("Key takeaways:");
133 println!("- Services provide a higher-level API than raw store access");
134 println!("- Arc<RwLock<Store>> enables thread-safe concurrent operations");
135 println!("- Services use request/response DTOs for clean API contracts");
136 println!("- Services encapsulate business logic and validation");
137
138 Ok(())
139}