Agent skill

message-construction

Use when designing message structure, intent, and metadata for enterprise messaging systems based on Enterprise Integration Patterns (Hohpe & Woolf). USE FOR: message types, command vs event vs document messages, request-reply, correlation, message sequencing, expiration, format indicators DO NOT USE FOR: channel selection (use messaging-channels), routing rules (use message-routing)

Stars 163
Forks 31

Install this agent skill to your Project

npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/other/other/message-construction

Metadata

Additional technical details for this skill

author
Tyler-R-Kendrick
displayName
Message Construction

SKILL.md

Message Construction

Overview

Message Construction patterns define what goes inside a message -- its intent, structure, metadata, and lifecycle. A well-constructed message is self-describing, carries the right amount of data, and enables the messaging system to route, correlate, and expire it correctly. Hohpe & Woolf identify patterns that address the intent of a message, how to correlate requests with replies, and how to manage message lifecycles.

Patterns

Command Message

Encodes an instruction to perform an action. Sent to a specific receiver on a Point-to-Point Channel.

json
{
  "messageType": "command",
  "command": "PlaceOrder",
  "messageId": "cmd-8a3f-4b2c",
  "timestamp": "2025-01-15T10:30:00Z",
  "body": {
    "customerId": "cust-001",
    "items": [
      { "sku": "WIDGET-42", "quantity": 3 }
    ],
    "shippingAddress": "123 Main St"
  }
}

When to use: Invoking a specific action on a specific system -- order placement, account creation, state mutations.

Document Message

Carries data without prescribing what the receiver should do with it. The sender transfers information; the receiver decides the action.

json
{
  "messageType": "document",
  "documentType": "CustomerProfile",
  "messageId": "doc-9c4e-7d1a",
  "timestamp": "2025-01-15T10:31:00Z",
  "body": {
    "customerId": "cust-001",
    "name": "Jane Smith",
    "email": "[email protected]",
    "tier": "gold",
    "lifetimeValue": 12500.00
  }
}

When to use: Data synchronisation, reporting feeds, transferring reference data between systems.

Event Message

Notifies subscribers that something has happened. The sender does not dictate what receivers should do.

json
{
  "messageType": "event",
  "eventType": "OrderPlaced",
  "messageId": "evt-2b7d-9e4f",
  "timestamp": "2025-01-15T10:32:00Z",
  "body": {
    "orderId": "order-5678",
    "customerId": "cust-001",
    "totalAmount": 149.97,
    "placedAt": "2025-01-15T10:30:00Z"
  }
}

When to use: Decoupled notification -- order placed, payment received, user registered. Publish on a Pub-Sub Channel.

Request-Reply

A two-message exchange: the requestor sends a request and waits for a reply on a dedicated reply channel.

json
// Request
{
  "messageType": "request",
  "messageId": "req-3c8a-1f2e",
  "replyTo": "channel://inventory-replies",
  "timestamp": "2025-01-15T10:33:00Z",
  "body": {
    "query": "CheckStock",
    "sku": "WIDGET-42"
  }
}

// Reply
{
  "messageType": "reply",
  "messageId": "rpl-7d4b-5a3c",
  "correlationId": "req-3c8a-1f2e",
  "timestamp": "2025-01-15T10:33:02Z",
  "body": {
    "sku": "WIDGET-42",
    "availableQuantity": 150,
    "warehouse": "US-EAST"
  }
}

When to use: When the sender needs a response but still wants temporal decoupling -- stock checks, credit approvals, price lookups.

Return Address

Embeds the reply channel address in the request message so the receiver knows where to send the reply.

json
{
  "messageId": "req-4a9b-2c1d",
  "replyTo": "channel://order-service/replies",
  "body": { "query": "GetOrderStatus", "orderId": "order-5678" }
}

When to use: Any Request-Reply scenario. Essential when multiple requestors share the same request channel.

Correlation Identifier

A unique identifier placed in the reply message that references the original request, allowing the requestor to match replies to their requests.

json
// Request (contains messageId)
{
  "messageId": "req-5b0c-3d2e",
  "replyTo": "channel://replies",
  "body": { "action": "ValidateAddress", "address": "123 Main St" }
}

// Reply (correlationId matches the request's messageId)
{
  "messageId": "rpl-8e1f-6a4b",
  "correlationId": "req-5b0c-3d2e",
  "body": { "valid": true, "normalised": "123 Main Street, Suite 100" }
}

When to use: Always use with Request-Reply. Critical when a requestor has multiple outstanding requests.

Message Sequence

Marks messages as part of an ordered series when a large dataset must be split across multiple messages.

json
{
  "messageId": "seq-6c1d-4e3f",
  "sequenceId": "batch-2025-01-15",
  "sequencePosition": 2,
  "sequenceSize": 5,
  "isLast": false,
  "body": {
    "records": [
      { "id": "rec-101", "value": "..." },
      { "id": "rec-102", "value": "..." }
    ]
  }
}

When to use: Transferring large datasets that exceed message size limits, ordered batch processing, streaming results.

Message Expiration

Sets a time-to-live (TTL) on a message so it is discarded if not consumed before the deadline.

json
{
  "messageId": "exp-7d2e-5f4a",
  "timestamp": "2025-01-15T10:30:00Z",
  "expiration": "2025-01-15T10:35:00Z",
  "body": {
    "type": "FlashSalePrice",
    "sku": "WIDGET-42",
    "price": 9.99
  }
}

When to use: Time-sensitive data (price quotes, session tokens, flash sales), preventing stale commands from executing.

Format Indicator

Embeds version or format metadata in the message so consumers can handle multiple message schema versions.

json
{
  "messageId": "fmt-8e3f-6a5b",
  "schemaVersion": "2.1",
  "contentType": "application/vnd.mycompany.order.v2+json",
  "body": {
    "orderId": "order-5678",
    "lineItems": [
      { "sku": "WIDGET-42", "qty": 3, "unitPrice": 49.99 }
    ]
  }
}

When to use: Schema evolution, multi-version consumers, gradual migration between message formats.

Message Anatomy Reference

json
{
  "messageId": "unique-id",
  "correlationId": "original-request-id",
  "causationId": "immediate-cause-message-id",
  "messageType": "command | event | document | request | reply",
  "schemaVersion": "1.0",
  "contentType": "application/json",
  "timestamp": "2025-01-15T10:30:00Z",
  "expiration": "2025-01-15T11:30:00Z",
  "replyTo": "channel://replies",
  "sequenceId": "batch-id",
  "sequencePosition": 1,
  "sequenceSize": 10,
  "headers": {
    "source": "order-service",
    "tenantId": "tenant-42"
  },
  "body": { }
}

Choosing the Right Message Type

Intent Pattern
Tell a system to do something Command Message
Transfer data without prescribing action Document Message
Announce something happened Event Message
Ask a question and wait for an answer Request-Reply
Match a reply to its request Correlation Identifier + Return Address
Send large data across multiple messages Message Sequence
Prevent stale messages from being processed Message Expiration
Support multiple schema versions Format Indicator

Best Practices

  • Give every message a unique messageId -- it is the foundation of idempotency, deduplication, and correlation.
  • Prefer Event Messages for cross-service communication; they create the loosest coupling.
  • Use Command Messages only when you intend exactly one receiver to act.
  • Always include a correlationId in replies so requestors can match responses.
  • Set expiration on time-sensitive messages rather than relying on consumers to check timestamps.
  • Version your message schemas from day one using Format Indicator; schema evolution is inevitable.
  • Keep message bodies lean -- carry references (IDs, URIs) rather than full object graphs when possible.
  • Include timestamp and source in every message for observability and debugging.

Expand your agent's capabilities with these related and highly-rated skills.

Didn't find tool you were looking for?

Be as detailed as possible for better results