cardinal-base

Crates.iocardinal-base
lib.rscardinal-base
version0.2.41
created_at2025-09-26 03:07:51.562916+00
updated_at2025-11-28 16:35:45.249982+00
descriptionDependency injection and routing primitives for the Cardinal gateway
homepagehttps://github.com/andrespirela/cardinal
repositoryhttps://github.com/andrespirela/cardinal
max_upload_size
id1855367
size128,896
(andreespirela)

documentation

README

cardinal-base

cardinal-base underpins the gateway’s dependency graph. It hosts the DI container, routing utilities, and destination resolver used everywhere else.

Components

  • CardinalContext – owns the active CardinalConfig, tracks provider registrations, and constructs providers on demand. Scope-aware (Singleton vs Transient) with cycle detection to keep async factories honest.
  • Provider traits – implement Provider for any type you want to resolve later. Register with register, register_with_factory, or register_singleton_instance.
  • CardinalRouter – small wrapper around matchit::Router; used by destinations to match HTTP method + path and extract path parameters.
  • DestinationContainer – builds DestinationWrappers from config, supplies per-destination middleware lists, and picks a backend by path segment or subdomain.

How it fits

At runtime the flow looks like this:

CardinalBuilder
   └─ registers providers in CardinalContext
        ├─ DestinationContainer (maps host/path → backend + middleware)
        ├─ PluginContainer (middleware registry)
        └─ any user-provided services

When cardinal-proxy handles a request it grabs the DestinationContainer and (if routes were declared) queries the CardinalRouter to validate the path and extract parameters. Middleware lists are pulled from each DestinationWrapper and fed to the plugin runner.

Adding new providers

struct Metrics;

#[async_trait::async_trait]
impl Provider for Metrics {
    async fn provide(ctx: &CardinalContext) -> Result<Self, CardinalError> {
        // optional: use ctx.config to decide setup
        Ok(Metrics)
    }
}

context.register::<Metrics>(ProviderScope::Singleton);

Later, middleware or infrastructure code can ask for context.get::<Metrics>().await? and work with the shared instance.

Commit count: 0

cargo fmt