Эта страница переведена с английского языковой моделью. При любом расхождении верен английский оригинал.
AsyncAPI-документ
asyncapi gen печатает AsyncAPI-документ магазина: все темы, кто их читает и пишет, схемы, ограничение попыток и описание, которое приложение даёт себе.
Документ строится по самому приложению, поэтому он не может описать тему, которую код не использует.
Каждая подписка - это операция receive, каждый ответ и каждый слот - операция send.
Схема полезной нагрузки берётся из её derive-макроса JsonSchema, а doc-комментарий становится описанием.
max_attempts и dead_letter указываются на операции, поэтому читатель видит, куда попадает сообщение, обработка которого не удаётся.
Раздел AsyncAPI описывает серверы, схемы безопасности и раздачу документа по HTTP.
Для документа нужна фича asyncapi крейта.
Точка входа
main.rs собирает магазин на in-memory брокере.
#[ruststream::app] даёт исполняемому файлу команды: run запускает магазин, asyncapi gen печатает документ.
- Макросы
- Вручную
/// `run` starts the shop; `asyncapi gen` prints its AsyncAPI document.
#[ruststream::app(flavor = "current_thread")]
fn app() -> impl App<State = Shop> {
service::shop(MemoryBroker::new())
}
fn app() -> impl App<State = Shop> {
service::shop(MemoryBroker::new())
}
/// What `#[ruststream::app]` writes: `run` starts the shop; `asyncapi gen` prints its AsyncAPI
/// document.
fn main() -> ExitCode {
run_main_on(AppRuntime::CurrentThread, app)
}
Что магазин сообщает о себе
AppInfo - это блок info документа: название, версия, описание, контакт, лицензия и теги.
- Макросы
- Вручную
/// What the AsyncAPI document says about the shop.
fn info() -> AppInfo {
AppInfo::new("shop", "0.1.0")
.description("Takes orders, charges them, ships them and tells the customer.")
.contact(Contact::new().name("Shop team").email("shop@example.com"))
.license(License::new("Apache-2.0"))
.tag(Tag::new("orders"))
}
/// What the AsyncAPI document says about the shop.
fn info() -> AppInfo {
AppInfo::new("shop", "0.1.0")
.description("Takes orders, charges them, ships them and tells the customer.")
.contact(Contact::new().name("Shop team").email("shop@example.com"))
.license(License::new("Apache-2.0"))
.tag(Tag::new("orders"))
}
Документ
cargo run --example guide --features testing,macros,memory,json,cbor,asyncapi -- asyncapi gen --yaml
Операция подписчика charge читает тему, отвечает в payments.settled и объявляет ограничение попыток:
receive_payments_requested:
action: receive
channel:
$ref: '#/channels/payments.requested'
messages:
- $ref: '#/channels/payments.requested/messages/PaymentRequest'
description: Charges an order through the payment provider.
reply:
channel:
$ref: '#/channels/payments.settled'
messages:
- $ref: '#/channels/payments.settled/messages/Paid'
x-ruststream-retry:
maxAttempts: 5
deadLetter: payments.dead
Обе формы магазина выдают одинаковый документ.
Тест в каждой из них сравнивает документ с examples/guide/asyncapi.json, поэтому любое изменение темы видно на ревью.