/ examples / fetch_with_filters.rs
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  }