Backstage Client Library
The backstage-client library is a Rust-based client for interacting with the Backstage API. It allows you to retrieve various entities from the Backstage API catalog, including components, APIs, resources, systems, groups, locations, domains, and templates.
Features
- Retrieve Entities: Fetch different types of entities from the Backstage API catalog.
- Filter Support: Use filters to retrieve specific kinds of entities.
Supported Entity Kinds
The library supports the following entity kinds:
- Component: Represents a component in the Backstage catalog.
- API: Represents an API in the Backstage catalog.
- Resource: Represents a resource in the Backstage catalog.
- System: Represents a system in the Backstage catalog.
- Group: Represents a group in the Backstage catalog.
- Location: Represents a location in the Backstage catalog.
- Domain: Represents a domain in the Backstage catalog.
- Template: Represents a template in the Backstage catalog.
Installation
Add the backstage-client crate to your Cargo.toml file:
[dependencies]
backstage-client = "0.1.2"
tokio = { version = "1", features = ["full"] }
log = "0.4"
env_logger = "0.10"
Usage
Example 1: Fetching all Entities
Here's an example of how to use the backstage-client library to fetch all entities from the Backstage API catalog:
use backstage_client::{BackstageClient, entities::Entity, ClientError};
use log::{info, error};
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
env_logger::init();
let base_url = env::var("BACKSTAGE_URL")
.unwrap_or_else(|_| "https://backstage.example.com".to_string());
let token = env::var("BACKSTAGE_TOKEN")
.expect("BACKSTAGE_TOKEN environment variable must be set");
let client = BackstageClient::new(&base_url, &token)?;
match client.fetch_entities::<Entity>(None).await {
Ok(entities) => {
info!("Successfully fetched {} entities", entities.len());
for entity in entities.iter().take(3) {
info!("Entity: {} ({})", entity.name(), entity.kind());
}
}
Err(e) => {
error!("Error fetching entities: {}", e);
return Err(e.into());
}
}
Ok(())
}
Example 2: Fetching Entities with Filters
You can also use filters to retrieve specific kinds of entities. Here's an example of how to fetch components of type service:
use backstage_client::{BackstageClient, entities::Entity, ClientError};
use log::{info, error};
use std::{collections::HashMap, env};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
env_logger::init();
let base_url = env::var("BACKSTAGE_URL")
.unwrap_or_else(|_| "https://backstage.example.com".to_string());
let token = env::var("BACKSTAGE_TOKEN")
.expect("BACKSTAGE_TOKEN environment variable must be set");
let client = BackstageClient::new(&base_url, &token)?;
let mut filters = HashMap::new();
filters.insert("kind".to_string(), "Component".to_string());
filters.insert("spec.type".to_string(), "service".to_string());
match client.fetch_entities::<Entity>(Some(filters)).await {
Ok(components) => {
info!("Successfully fetched {} components", components.len());
for component in components.iter().take(5) {
info!("Component: {} - {}",
component.name(),
component.description().unwrap_or("No description")
);
}
}
Err(e) => {
error!("Error fetching components: {}", e);
return Err(e.into());
}
}
Ok(())
}
Example 3: Getting a Specific Entity
You can retrieve a specific entity by its kind, namespace, and name:
use backstage_client::{BackstageClient, entities::Entity, ClientError};
use log::{info, error};
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
env_logger::init();
let base_url = env::var("BACKSTAGE_URL")
.unwrap_or_else(|_| "https://backstage.example.com".to_string());
let token = env::var("BACKSTAGE_TOKEN")
.expect("BACKSTAGE_TOKEN environment variable must be set");
let client = BackstageClient::new(&base_url, &token)?;
match client.get_entity::<Entity>("Component", Some("default"), "my-service").await {
Ok(entity) => {
info!("Found entity: {}", entity);
info!(" Kind: {}", entity.kind());
info!(" Name: {}", entity.name());
info!(" Namespace: {}", entity.namespace());
if let Some(description) = entity.description() {
info!(" Description: {}", description);
}
}
Err(e) => {
error!("Error fetching entity: {}", e);
return Err(e.into());
}
}
Ok(())
}