Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Public Traits

Module

#![allow(unused)]
fn main() {
pub trait Module {
    fn register() -> ModuleMetadata;
}
}

Injectable

#![allow(unused)]
fn main() {
pub trait Injectable: Send + Sync + 'static {
    fn create(container: &Container) -> BoxFuture<'_, Result<Self>>
    where
        Self: Sized;

    fn dependencies() -> Vec<ProviderDependency>
    where
        Self: Sized;

    fn on_module_init(&self) -> BoxFuture<'_, Result<()>>;
    fn on_bootstrap(&self) -> BoxFuture<'_, Result<()>>;
    fn on_shutdown(&self) -> BoxFuture<'_, Result<()>>;
}
}

Implement manually for owned state, custom construction, or lifecycle hooks. A manual implementation must declare every provider it resolves from create:

#![allow(unused)]
fn main() {
fn dependencies() -> Vec<ProviderDependency> {
    provider_dependencies![Database, Config]
}
}

Use provider_dependencies![] when it resolves no providers. The compiler requires this method, and Caelix rejects an undeclared container.resolve::<T>() while constructing the provider. #[injectable] supplies the declaration automatically for its Arc<T> fields; Arc<Logger> is excluded because it uses the scoped logger API rather than DI resolution.

Config

#![allow(unused)]
fn main() {
pub trait Config: Injectable + Sized {
    fn load() -> Result<Self>;
    fn load_from(path: impl AsRef<Path>) -> Result<Self>;
}
}

#[derive(Config)] implements this trait and Injectable. load uses the optional working-directory .env; load_from requires the supplied file. Both sources are overlaid by process environment values and validated before returning. Precedence is process environment, file, default = "...", then None for a directly declared Option<T> field. ConfigModule<T> registers the default source, while ConfigModule<T, F> uses the path returned by a ConfigFile implementation. See Typed Configuration for DI and override examples.

load_from is also useful when a caller needs a one-off explicit path:

#![allow(unused)]
fn main() {
let config = AppConfig::load_from("/etc/my-service/production.env")?;
}

Missing required fields, conversion failures, validation failures, and missing or malformed explicit files return startup errors. The default missing .env is allowed. Diagnostics include field and environment names without exposing secret values.

Controller

Generated by #[controller] for normal use. Manual implementations register routes into an adapter-specific service config.

#![allow(unused)]
fn main() {
pub trait Controller {
    fn base_path() -> &'static str;
    fn routes() -> &'static [RouteDef] {
        &[]
    }
    fn register_routes(cfg: &mut dyn Any);
}
}

Implement manually only when writing adapter-specific route integration.

Guard

#![allow(unused)]
fn main() {
pub trait Guard: Send + Sync + 'static {
    fn can_activate<'a>(&'a self, ctx: &'a RequestContext) -> BoxFuture<'a, Result<bool>>;
}
}

Interceptor

#![allow(unused)]
fn main() {
pub trait Interceptor: Send + Sync + 'static {
    fn intercept<'a>(
        &'a self,
        ctx: &'a RequestContext,
        next: Next<'a>,
    ) -> BoxFuture<'a, Result<HttpResponse>>;
}
}

EventHandler<E>

#![allow(unused)]
fn main() {
pub trait EventHandler<E>: Send + Sync + 'static {
    fn handle(&self, event: E) -> BoxFuture<'_, Result<()>>;
}
}

Event types must be Clone + Send + Sync + 'static.

RegisterableEventHandler

#![allow(unused)]
fn main() {
pub trait RegisterableEventHandler: Injectable {
    type Event: Clone + Send + Sync + 'static;
}
}

Implement this to use .event_handler::<Handler>(). Use .event_handler_for::<Event, Handler>() when you want to avoid the marker implementation.

CacheStore

Custom cache backends implement get, set, delete, and clear over JSON values.

#![allow(unused)]
fn main() {
pub trait CacheStore: Send + Sync + 'static {
    fn get(&self, key: String) -> BoxFuture<'_, Result<Option<serde_json::Value>>>;
    fn set(
        &self,
        key: String,
        value: serde_json::Value,
        ttl: Option<std::time::Duration>,
    ) -> BoxFuture<'_, Result<()>>;
    fn delete(&self, key: String) -> BoxFuture<'_, Result<()>>;
    fn clear(&self) -> BoxFuture<'_, Result<()>>;
}
}

Implement manually for Redis, Memcached, database-backed caches, or test stores. Caelix does not provide automatic HTTP response caching.

Response conversion

IntoCaelixResponse converts controller return values into HttpResponse. Caelix implements it for its response wrappers and common serializable results. Implement it for an application response wrapper when centralized status, headers, cookies, or body conversion is needed.

Microservices

Microservice: Injectable is generated by #[microservice]; its definition returns provider and handler metadata. Do not implement MessageHandlerDef plumbing manually in normal applications.

Gateways

Gateway: Injectable supplies registration metadata and is normally generated by #[gateway]. WebSocketGateway: Injectable is the public RFC 6455 callback contract. Custom runtime transports may implement WebSocketTransport. RegisteredWebSocketGateway is a framework composition marker and should not be implemented directly. With socketio, SocketIoGateway is generated for annotated gateways.

Documentation and framework internals

OpenApiError is the public extension point for custom documented error types. Controller, Microservice, Gateway, RegisteredWebSocketGateway, and RegisterableEventHandler are primarily macro/registration metadata traits. Application authors normally implement behavior traits (Module, Injectable, Guard, Interceptor, EventHandler, CacheStore, WebSocketGateway, WebSocketTransport, IntoCaelixResponse, and custom OpenApiError) and let macros produce framework metadata.