fetch_with_filters.rs
1 //! Example: Fetch Entities with Filters 2 //! 3 //! This example demonstrates how to fetch entities from a Backstage catalog 4 //! using various filters to narrow down the results. 5 //! 6 //! Usage: 7 //! BACKSTAGE_URL=https://your-backstage.com BACKSTAGE_TOKEN=your-token cargo run --example fetch_with_filters 8 9 use backstage_client::{entities::Entity, BackstageClient}; 10 use log::{error, info}; 11 use std::{collections::HashMap, env}; 12 13 #[tokio::main] 14 async fn main() -> Result<(), Box<dyn std::error::Error>> { 15 // Initialize logging 16 env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("INFO")).init(); 17 18 // Get configuration from environment variables 19 let base_url = 20 env::var("BACKSTAGE_URL").unwrap_or_else(|_| "https://demo.backstage.io".to_string()); 21 let token = 22 env::var("BACKSTAGE_TOKEN").expect("BACKSTAGE_TOKEN environment variable must be set"); 23 24 info!("Connecting to Backstage at: {}", base_url); 25 26 // Create a new Backstage client 27 let client = BackstageClient::new(&base_url, &token)?; 28 29 // Example 1: Fetch only Components 30 info!("\n=== Fetching all Components ==="); 31 let mut filters = HashMap::new(); 32 filters.insert("kind".to_string(), "Component".to_string()); 33 34 match client.fetch_entities::<Entity>(Some(filters)).await { 35 Ok(components) => { 36 info!("Found {} components", components.len()); 37 for (i, component) in components.iter().take(3).enumerate() { 38 info!( 39 " {}. {} - {}", 40 i + 1, 41 component.name(), 42 component.description().unwrap_or("No description") 43 ); 44 } 45 if components.len() > 3 { 46 info!(" ... and {} more components", components.len() - 3); 47 } 48 } 49 Err(e) => { 50 error!("Error fetching components: {}", e); 51 } 52 } 53 54 // Example 2: Fetch Components of type "service" 55 info!("\n=== Fetching Service Components ==="); 56 let mut service_filters = HashMap::new(); 57 service_filters.insert("kind".to_string(), "Component".to_string()); 58 service_filters.insert("spec.type".to_string(), "service".to_string()); 59 60 match client.fetch_entities::<Entity>(Some(service_filters)).await { 61 Ok(services) => { 62 info!("Found {} service components", services.len()); 63 for service in services.iter().take(3) { 64 info!( 65 " - {} ({}): {}", 66 service.name(), 67 service.namespace(), 68 service.description().unwrap_or("No description") 69 ); 70 } 71 } 72 Err(e) => { 73 error!("Error fetching service components: {}", e); 74 } 75 } 76 77 // Example 3: Fetch APIs 78 info!("\n=== Fetching APIs ==="); 79 let mut api_filters = HashMap::new(); 80 api_filters.insert("kind".to_string(), "API".to_string()); 81 82 match client.fetch_entities::<Entity>(Some(api_filters)).await { 83 Ok(apis) => { 84 info!("Found {} APIs", apis.len()); 85 for api in apis.iter().take(3) { 86 info!( 87 " - {} in namespace '{}': {}", 88 api.name(), 89 api.namespace(), 90 api.description().unwrap_or("No description") 91 ); 92 93 // Show entity reference 94 info!(" Entity ref: {}", api.entity_ref()); 95 } 96 } 97 Err(e) => { 98 error!("Error fetching APIs: {}", e); 99 } 100 } 101 102 // Example 4: Fetch entities in a specific namespace 103 info!("\n=== Fetching entities in 'default' namespace ==="); 104 let mut namespace_filters = HashMap::new(); 105 namespace_filters.insert("metadata.namespace".to_string(), "default".to_string()); 106 107 match client 108 .fetch_entities::<Entity>(Some(namespace_filters)) 109 .await 110 { 111 Ok(default_entities) => { 112 info!( 113 "Found {} entities in 'default' namespace", 114 default_entities.len() 115 ); 116 117 // Group by kind 118 let mut kind_counts = HashMap::new(); 119 for entity in &default_entities { 120 *kind_counts.entry(entity.kind()).or_insert(0) += 1; 121 } 122 123 info!("Breakdown by kind:"); 124 for (kind, count) in kind_counts { 125 info!(" {}: {}", kind, count); 126 } 127 } 128 Err(e) => { 129 error!("Error fetching entities in default namespace: {}", e); 130 } 131 } 132 133 // Example 5: Fetch entities with specific tags 134 info!("\n=== Fetching entities with 'java' tag ==="); 135 let mut tag_filters = HashMap::new(); 136 tag_filters.insert("metadata.tags".to_string(), "java".to_string()); 137 138 match client.fetch_entities::<Entity>(Some(tag_filters)).await { 139 Ok(java_entities) => { 140 info!("Found {} entities with 'java' tag", java_entities.len()); 141 for entity in java_entities.iter().take(3) { 142 info!(" - {} ({})", entity.name(), entity.kind()); 143 if let Some(tags) = entity.tags() { 144 info!(" Tags: {}", tags.join(", ")); 145 } 146 } 147 } 148 Err(e) => { 149 error!("Error fetching entities with java tag: {}", e); 150 } 151 } 152 153 info!("\n=== Filter Examples Complete ==="); 154 info!("Try modifying the filters above to explore your Backstage catalog!"); 155 156 Ok(()) 157 }