lilydocs
HTTP APIWebSocketConsumer
Mesaj işleme3 dk okuma

Özel extractor ve decoder

Metadata veya payload verisini kendi typed extractor sözleşmenizle işleyin.

Built-in extractor'lar ihtiyacınızı karşılamadığında metadata'dan uygulama değeri çıkarabilir veya body için özel decoder yazabilirsiniz. İki işin trait'i ayrıdır: FromDeliveryParts body authority'yi tüketmez, FromDelivery tek terminal payload sahibidir.

Metadata extractor yazın#

Rust
use lilyrs::queue::{
    DeliveryInvocation, EventId, FromDeliveryParts, QueueHandlerError,
};

struct MessageIdentity(EventId);

impl FromDeliveryParts for MessageIdentity {
    type Rejection = QueueHandlerError;

    async fn from_delivery_parts(invocation: &mut DeliveryInvocation)
        -> Result<Self, Self::Rejection>
    {
        Ok(Self(invocation.context().event_id()))
    }
}

MessageIdentity, doğrulanmış envelope kimliğini owned uygulama tipine taşır. Handler'da payload'dan önce MessageIdentity(id): MessageIdentity parametresi kullanılabilir. Bu dönüşüm veri biçimini değiştirir; kendiliğinden deduplication kaydı tutmaz.

DeliveryInvocation bounded metadata, read-only DI provider ve typed local state sunar. Parts extractor owned değer döndürür; invocation'a referans taşıyan handler parametresi üretmez. Ret tipi Into<QueueHandlerError> + Send olmalıdır. Optional extraction gerekiyorsa OptionalFromDeliveryParts ile gerçek yokluğu Ok(None) olarak modelleyin; bozuk veriyi yokluk gibi gizlemeyin.

Özel body sözleşmesi tanımlayın#

Aşağıdaki tam alternatif uygulama, vendor.order-id content token'ıyla gelen UTF-8 sayıyı OrderId değerine çevirir. İlk uygulamanın Cargo manifesti ve lily.toml dosyası kullanılabilir; src/main.rs yerine bu dosyayı koyun.

custom_extractors.rs
use lilyrs::{
    consumer::{Consumer, ConsumerError, Injectable, ServiceTrait},
    queue::{DeliveryPayloadInput, FromDelivery, QueueHandlerError, QueuePayloadKind, queue, queue_service},
};
struct OrderId(u64);
impl FromDelivery for OrderId {
    const PAYLOAD_KIND: QueuePayloadKind = QueuePayloadKind::Custom;
    type Rejection = QueueHandlerError;
    async fn from_delivery(mut input: DeliveryPayloadInput<'_>) -> Result<Self, Self::Rejection> {
        let body = input.take_body()?;
        let text = std::str::from_utf8(&body)
            .map_err(|_| QueueHandlerError::permanent("ORDER_ID_ENCODING_INVALID"))?;
        let id = text.parse::<u64>()
            .map_err(|_| QueueHandlerError::permanent("ORDER_ID_INVALID"))?;
        if id == 0 { return Err(QueueHandlerError::permanent("ORDER_ID_ZERO")); }
        Ok(Self(id))
    }
}
#[derive(Default, Injectable)]
#[service(lifetime = "Singleton")]
struct OrderWorker;
impl ServiceTrait for OrderWorker {}
#[queue_service]
impl OrderWorker {
    #[queue("orders.created", version = 1, content = "vendor.order-id")]
    async fn created(&self, OrderId(id): OrderId) -> Result<(), QueueHandlerError> {
        println!("{id}");
        Ok(())
    }
}
#[tokio::main]
async fn main() -> Result<(), ConsumerError> { Consumer::run().await }

PAYLOAD_KIND = QueuePayloadKind::Custom, registry'ye bu extractor'ın custom body authority olduğunu bildirir. take_body() aynı input üzerinde body'yi bir kez alır. UTF-8, sayı biçimi ve sıfır kontrolü uygulama decoder'ının açık ret kararlarıdır; her biri safe code taşıyan permanent hata üretir.

Eşleşen producer kullanın#

İlk sayfadaki publish_json bu alternatif handler ile eşleşmez. Ayrı publisher uygulamasına aşağıdaki fonksiyonu ekleyip mevcut publish çağrısı yerine çağırın; container cleanup akışını koruyun:

Rust
async fn publish_order_id(
    publisher: &lilyrs::queue_client::QueueClientService,
) -> Result<(), Box<dyn std::error::Error>> {
    use lilyrs::queue_client::{CustomPublishContent, PublishSchemaVersion};
    let content = CustomPublishContent::try_new("vendor.order-id", "text/plain")?;
    publisher.publish_custom(
        "orders", "orders.created", PublishSchemaVersion::V1, content, b"42",
    ).await?;
    Ok(())
}

Publisher vendor.order-id token'ını, handler da aynı exact token'ı kullanır. Burada text/plain MIME seçilmesi content-kind'ı text yapmaz. Built-in json, text, binary token'ları kendi typed publish metotlarına ayrılmıştır.

Decoder sınırları ve belge üretimi#

Custom decoder transport boyut sınırlarını veya envelope doğrulamasını devre dışı bırakmaz. Blocking veya uzun CPU işi shared async executor'ı tutabilir; bir async timeout non-yielding işi preempt edemez. Decoder'daki dış çağrıları deadline ve cancellation politikasıyla tasarlayın.

Özel decoder yazmak AsyncAPI şemasını otomatik üretmez. AsyncAPI seçildiğinde custom/raw payload için açık schema veya opaque metadata'sı ve content type gerekir; handler'ı açıkça skip etmek de bir tercihtir.

Bu sayfanın kaynakları v0.1.0

Anlatım, incelenen framework commit’ine dayanır.

HIZLI BAŞLANGIÇ
Dokümantasyon
Kaynak kod