# Mediator (request/response + pipeline)
MediatR-style in-process mediator: `Input`, `InputHandler`, `send()`, optional pipeline behaviors.
## Quick start
```rust
use noema::{input, request, send};
use noema::core::{Container, Injectable};
use async_trait::async_trait;
#[input(u32)]
struct Ping;
struct PingHandler;
impl Injectable<Container> for PingHandler {
fn inject(_: &Container) -> Self { PingHandler }
}
#[async_trait]
impl noema::mediator::InputHandler<Ping> for PingHandler {
async fn handle(&self, _: std::sync::Arc<Ping>) -> noema::mediator::NoemaResult<u32> {
Ok(1)
}
}
request!(Ping: PingHandler);
let n = send(Ping).await?;
```
## Per-input pipeline
```rust
request!(CreateOrder: CreateOrderHandler => [ValidateOrder, LogRequest]);
```
Order: `ValidateOrder` → `LogRequest` → handler (first listed = outermost).
## Global pipeline (optional)
Use `global_request!` or `global_pipeline!` when you want behaviors on **every** request type they support:
```rust
use noema::global_pipeline;
global_pipeline! {
GlobalLog, Metrics;
CreateOrder: CreateOrderHandler => [ValidateOrder],
Ping: PingHandler,
}
```
Without this macro, use `request!` alone — no global behaviors, no extra setup.
## Rules
- Handler and each behavior: concrete type + `Injectable<Container>`.
- Each `send()` creates **new** behavior/handler instances via `inject()` (not singleton).
- No `Any`, no `TypeId`, no runtime pipeline registry — all wiring is compile-time.
- Global behaviors must implement `PipelineBehavior<I>` for each `Input` they should wrap (often via generic `impl<I: Input + …> PipelineBehavior<I>`).
## Features
Enable in `Cargo.toml`:
```toml
noema = { version = "0.3", features = ["mediator"] }
```