#callback #integration #supplier #failure #name

supplier_kit

A modular toolkit for managing and grouping dynamic data suppliers

1 unstable release

Uses new Rust 2024

0.1.0 May 17, 2025

#703 in Web programming

Download history 118/week @ 2025-05-14

118 downloads per month

Apache-2.0

36KB
182 lines

supplier_kit

A modular toolkit for managing and grouping dynamic data suppliers.

supplier_kit helps you build robust and extensible architectures that rely on multiple external or internal data providers — known as suppliers. It is ideal for use cases such as federated API calls, service orchestration, or data aggregation (e.g., e-commerce platforms).


✨ Features

  • Supplier trait: defines a common interface for all data providers
  • SupplierRegistry: a container for registering and accessing suppliers by name
  • SupplierGroup: abstraction to query multiple suppliers in a batch
  • SupplierGroupResult: returns per-supplier successes and failures
  • register_suppliers! macro: for easy supplier registration
  • Utility helpers like add_supplier_from_registry and add_suppliers_from_registry as an option

🔧 Use Cases

  • Aggregating product listings from multiple platforms
  • Wrapping multiple internal microservices behind unified access
  • Resilient systems that gracefully handle partial failure

🚀 Quick Start

Example: Registering and Querying Multiple Suppliers

This example demonstrates how to use SupplierRegistry and BasicSupplierGroup to register multiple suppliers, group them, and execute a Search operation.

It includes:

  • Using the register_suppliers! macro
  • Handling partial failures using add_suppliers_from_registry
  • Group querying with SupplierGroup trait
use supplier_kit::models::{SupplierRequest, SupplierResponse, SupplierOperation};
use supplier_kit::supplier::{Supplier, SupplierRegistry};
use supplier_kit::supplier_group::{SupplierGroup, BasicSupplierGroup, SupplierGroupResult};
use supplier_kit::errors::SupplierError;
use supplier_kit::register_suppliers;
use serde_json::json;
use supplier_kit::utils::add_suppliers_from_registry;

struct MockSupplier {
    name: String,
    should_fail: bool,
}

impl MockSupplier {
    fn new(name: &str, should_fail: bool) -> Self {
        Self {
            name: name.to_string(),
            should_fail,
        }
    }
}

impl Supplier for MockSupplier {
    fn name(&self) -> &str {
        &self.name
    }

    fn query(&self, request: SupplierRequest) -> Result<SupplierResponse, SupplierError> {
        if self.should_fail {
            Err(SupplierError::Internal(format!("{} failed", self.name)))
        } else {
            Ok(SupplierResponse {
                data: json!({
                    "supplier": self.name,
                    "params": request.params
                }),
            })
        }
    }
}

fn main() -> Result<(), SupplierError> {
    let mut registry = SupplierRegistry::new();
    register_suppliers!(
        registry,
        "s1" => MockSupplier::new("s1", false),
        "s2" => MockSupplier::new("s2", true),
        "s3" => MockSupplier::new("s3", false),
    );

    let mut group = BasicSupplierGroup::new("example_group");

    let failures = add_suppliers_from_registry(&mut group, &registry, &["s1", "s2", "s4"]);

    if !failures.is_empty() {
        for (name, err) in failures {
            println!("Failed to add '{}': {}", name, err);
        }
    }

    let request = SupplierRequest {
        operation: SupplierOperation::Search,
        params: json!({ "keyword": "laptop" }),
    };

    let result: SupplierGroupResult = group.query(request);

    println!("Successes:");
    for (name, response) in result.successes {
        println!("- [{}] Response: {}", name, response.data);
    }

    println!("Failures:");
    for (name, error) in result.failures {
        println!("- [{}] Error: {}", name, error);
    }

    Ok(())
}

📄 License

Licensed under the Apache-2.0 license


👨 Author

Jerry Maheswara jerrymaheswara@gmail.com


❤️ Built with Love in Rust

This project is built with ❤️ using Rust — a systems programming language that is safe, fast, and concurrent.
Rust is the perfect choice for building reliable and efficient applications.


🤝 Contributing

Pull requests, issues, and feedback are welcome!
If you find this crate useful, give it a ⭐ and share it with others in the Rustacean community.


Dependencies

~0.6–1.5MB
~33K SLoC