Postboy Help

The Base Message Contract

Purpose

Every message in Postboy, regardless of its specific role, extends the abstract PostboyMessage class. This common foundation ensures that all messages share:

  • a stable identity the bus can rely on

  • mutable metadata for contextual enrichment

  • a predictable structure for middleware and subscribers

Understanding this base contract helps you see how the three message families fit together and why they can coexist within the same pipeline.

Public API

PostboyMessage defines a minimal but essential interface:

  • id: string

  • metadata: PostboyMessageMetadata

  • setMetadata(metadata: Partial<PostboyMessageMetadata>): this

id

A unique string derived from the message class itself. The bus uses this identifier to resolve subscriptions, executors, and any middleware that cares about a specific message type.

Concrete message classes should provide their own static ID field:

class UserCreatedEvent extends PostboyGenericMessage { static readonly ID = 'user.created'; }

The id getter returns this static value, giving the runtime a stable reference.

metadata

A mutable object that stores additional context about the message. It can hold:

  • tags (e.g., tracing or categorisation strings)

  • timestamps

  • correlation identifiers

  • any other application‑specific annotations

The shape of PostboyMessageMetadata is intentionally minimal to allow flexible enrichment without breaking the contract.

setMetadata(metadata)

Merges the provided partial object into the existing metadata and returns the same message instance. This fluent API allows you to decorate a message during creation or within middleware before it reaches its final destination:

const message = new UserCreatedEvent('user-123') .setMetadata({tags: new Set(['user', 'tracked'])});

Interaction model

A PostboyMessage instance typically follows this sequence:

  1. A concrete message class is defined with a unique ID.

  2. An instance is created and optionally enriched with metadata.

  3. The message is sent through the bus (fire, fireCallback, or exec).

  4. The bus resolves the message by its id.

  5. Registered middleware may inspect or alter the flow.

  6. Subscribers or handlers react accordingly.

  7. The flow ends with either a side effect, a response, or a result.

Because PostboyMessage is abstract, you never use it directly — only through one of its concrete subclasses:

Each subclass adds its own semantics, but all rely on the same base contract for identity and metadata.

Why inheritance matters

Using a shared abstract base offers several benefits:

  • Unified infrastructure – Middleware, logging, and tracing operate on PostboyMessage without needing to know the specific flavour.

  • Stable identity – The static ID field eliminates the need for manual string constants scattered across the codebase.

  • Extensible metadatasetMetadata provides a standard way to enrich any message, keeping the API consistent.

At the same time, the concrete subclasses make the intended communication style explicit. You choose the right tool for the job, but the underlying machinery remains predictable.

Relationship to other contracts

Contract

Extends

Adds

PostboyGenericMessage

PostboyMessage

Broadcast semantics (one‑to‑many)

PostboyCallbackMessage<T>

PostboyMessage

Typed response handling

PostboyExecutor<T>

PostboyMessage

Explicit, direct execution

Despite their differences, any piece of code that can work with a PostboyMessage can also work with all three. This is what allows middleware to transparently observe or transform any message flowing through the bus.

Notes

  • PostboyMessage itself is abstract and cannot be instantiated directly.

  • Message identity is class‑based; each concrete message must define its own static ID.

  • Metadata is intentionally mutable — it is designed to be augmented during the lifecycle, not frozen at creation.

In short

PostboyMessage is the root contract of the Postboy message family. It provides a stable identity, shared metadata, and a common foundation that unifies event‑style, request/response, and explicit execution patterns within a single bus.

03 мая 2026