跳到主要内容
本页尚未翻译

下面显示的是英文原文。

Destinations

A message type declares where it goes: a fixed name, a name template with a setter per placeholder, or no name, left to the call.

#[derive(Outgoing)] makes a type publishable, and #[outgoing(name = "..")] declares its destination. A fixed name, "orders.confirmed", resolves the destination for every call site, so the publish needs no .to(..). A name template, "orders.{tenant}.placed", opens .to() with one setter per placeholder, and the publish exists only once every placeholder is bound. A template renders its name on each publish; a fixed name costs nothing per publish. A type without a name takes .to("dest") at every call site. A reply type declares a fixed name or none: the runtime publishes the reply and has nothing to bind a template's placeholders with, so a reply to a template does not compile. The generated AsyncAPI document reports each declared destination, a template as a channel with parameters.

Without the macros, the type implements OutgoingDestination by hand: FixedName, NameTemplate or CallerName as its Form. A template there also names the builder of its setters through TemplateAddress. The same attribute declares the message's header contract, #[outgoing(headers = Meta)], described on the Outgoing page of typed headers.

Example​

The three forms of a destination.

/// A fixed name: every publish of this type goes to `orders.confirmed`.
#[derive(Debug, PartialEq, Deserialize, Serialize, Outgoing)]
#[outgoing(name = "orders.confirmed")]
struct OrderConfirmed {
id: u64,
}

/// A name template: each placeholder becomes a setter on the publish builder.
#[derive(Debug, PartialEq, Deserialize, Serialize, Outgoing)]
#[outgoing(name = "orders.{tenant}.placed")]
struct OrderPlaced {
id: u64,
}

/// No name: the call site names the destination.
#[derive(Debug, PartialEq, Deserialize, Serialize, Outgoing)]
struct Notice {
id: u64,
}

Each publish fills only what its type leaves open.

#[subscriber("orders.incoming")]
async fn route(order: &Order, Out(orders): Out<impl Publisher, Orders>) -> HandlerOutcome {
let confirmed = orders
.message(&OrderConfirmed { id: order.id })
.publish()
.await;
let placed = orders
.message(&OrderPlaced { id: order.id })
.to()
.tenant(&order.tenant)
.publish()
.await;
let notice = orders
.message(&Notice { id: order.id })
.to("notices")
.publish()
.await;
if confirmed.is_err() || placed.is_err() || notice.is_err() {
return HandlerOutcome::retry();
}
HandlerOutcome::ack()
}