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

下面显示的是英文原文。

Headers

A NATS header is text: a name of printable ASCII without a colon and a one-line value; a header that does not fit fails the publish.

The framework's header map holds any bytes under any name, and NATS carries less. A value that is not UTF-8, a value with a line break, and a name with a colon or a space have no wire form. Such a header fails the publish with NatsError::Publish naming it, before anything reaches the server. The message is not sent without it, because a header that silently disappears changes what the message means. A message type declares its headers in its typed header contract, #[outgoing(headers = ..)], and a publish of that type that does not set them does not compile. Headers count toward the server's payload limit together with the payload. A delivery's headers are read with ctx.headers() or the Headers<T> extractor. A Core delivery that is a request carries its inbox as the reply-to header, which a responder answers on. The Nats- headers of JetStream are written by the policy and the publish steps.

Example​

The tenant of an invoice travels as a header; a tenant name with a line break fails the publish, and the order is dropped.

/// The header contract of an invoice: the tenant it belongs to travels as `x-tenant`.
#[derive(Debug, PartialEq, Deserialize, Serialize)]
struct Tenant {
#[serde(rename = "x-tenant")]
tenant: String,
}

#[derive(Debug, PartialEq, Deserialize, Serialize, Outgoing)]
#[outgoing(name = "invoices.issued", headers = Tenant)]
struct Invoice {
order_id: u64,
}

#[derive(OutSlot)]
#[publishes(Invoice)]
struct Invoices;

/// Issues the invoice of each order under its tenant. A tenant name with a line break has no
/// NATS form, so the publish fails and the order is dropped.
#[subscriber("orders.billed")]
async fn issue(order: &Order, Out(invoices): Out<impl Publisher, Invoices>) -> HandlerOutcome {
let tenant = Tenant {
tenant: order.tenant.clone(),
};
let sent = invoices
.message(&Invoice { order_id: order.id })
.with_headers(&tenant)
.publish()
.await;
match sent {
Ok(()) => HandlerOutcome::ack(),
Err(err) => {
tracing::error!(order.id, %err, "the invoice cannot carry its tenant");
HandlerOutcome::drop()
}
}
}