Messaging Decorators
Define TypeScript event subscriptions, event publication, queues, background jobs, enqueueing, dead-letter handling, and message processing with AxilJS.
Messaging Decorators
AxilJS messaging decorators describe event-driven and queue-based behavior as semantic metadata.
They define what an operation consumes, produces, queues, or processes without coupling application code to a specific message broker or queue implementation.
The core messaging decorators are:
@tOnEvent@tEmit@tOnce@tQueue@tJob@tEnqueue@tDeadLetter@tMessage
@tOnEvent
Subscribes a method to events matching a specified event name or pattern.
Event patterns allow a handler to subscribe to a family of related events.
Options
| Option | Type | Description |
|---|---|---|
async | boolean | Run the handler asynchronously |
priority | number | Handler priority; higher values execute first |
The decorator describes the subscription. The event consumer determines how the subscription is registered with the underlying messaging infrastructure.
@tEmit
Declares that an event should be published after a method completes successfully.
The method's return value can become the event payload.
This allows event publication to remain separate from broker-specific publishing code.
For operations that modify persistent state, @tEmit can also be combined with transactional messaging semantics such as @tOutbox.
@tOnce
Declares a one-time event subscription.
The subscription is removed after the first invocation.
This is useful for initialization, startup tasks, and one-time application events.
@tQueue
Declares a class as a queue processor.
The queue metadata defines the processing context, while individual job decorators define the work performed within that queue.
@tJob
Declares a background job handler within a queue.
Job configuration can describe retry behavior, backoff strategy, and execution timeout.
The queue consumer interprets this metadata and maps it to the underlying job-processing infrastructure.
@tEnqueue
Declares that a job should be enqueued after an operation completes.
This separates the business operation from direct interaction with the queue implementation.
For example, creating a user can declare that a welcome-email job should be queued without importing a broker-specific queue client into the business service.
@tDeadLetter
Declares dead-letter handling for terminally failed messages.
After the configured failure policy is exhausted, the messaging consumer can route the message to the declared dead-letter channel.
Dead-letter semantics are useful for isolating messages that require investigation or manual recovery.
@tMessage
Declares a handler for a messaging channel.
This semantic is distinct from event pub/sub and is intended for direct message-channel processing.
The messaging consumer determines how the channel is connected to the underlying broker.
Event-Driven Example
A typical event-driven flow can combine event publication and subscription:
The producer declares the event it emits, while the consumer declares the event it handles.
Neither service needs to encode broker-specific subscription or publication logic into the semantic declaration.
Queue Processing Example
Queue-based workloads can be expressed through a queue, job, and dead-letter policy:
The metadata describes:
- The queue being processed.
- The maximum processing concurrency.
- The job identity.
- Retry behavior.
- Execution timeout.
- Terminal failure routing.
The queue infrastructure can implement these policies independently of the worker's business logic.
Combining Messaging and Distributed Semantics
Messaging decorators can be combined with distributed-system decorators when reliable event processing is required.
Producer:
Consumer:
This separates:
- Database transaction semantics.
- Reliable event publication.
- Event subscription.
- Duplicate-message handling.
- Business processing.
Messaging Decorator Reference
| Decorator | Purpose |
|---|---|
@tOnEvent | Subscribes to an event or event pattern |
@tEmit | Publishes an event after successful execution |
@tOnce | Handles an event exactly once |
@tQueue | Declares a queue processor |
@tJob | Declares a background job handler |
@tEnqueue | Declares job enqueueing |
@tDeadLetter | Defines terminal failure routing |
@tMessage | Declares a messaging-channel handler |
These decorators form the messaging and queue category in the AxilJS decorator system.
Design Principle
Messaging decorators describe messaging intent rather than broker implementation.
For example:
The method declares what it consumes. It does not need to know whether the underlying infrastructure uses Kafka, RabbitMQ, Redis Streams, an in-process event bus, or another messaging system.
The consumer is responsible for translating the semantic metadata into the appropriate messaging infrastructure.
This preserves the AxilJS principle of independent consumers: decorators declare behavior, while infrastructure components implement it. The documentation describes this consumer model explicitly for AxilJS metadata.