Training Day

Publish-Subscribe Pattern

Decoupled communication where publishers send messages to topics and subscribers receive them

The publish-subscribe (pub/sub) pattern is a messaging pattern where senders (publishers) don't send messages directly to specific receivers (subscribers) but instead categorize messages into topics that subscribers can express interest in.

Publish-Subscribe Overview

Pub/sub offers several key characteristics that distinguish it from other patterns:

  • Decoupled communication: Publishers don't know which subscribers (if any) will receive messages
  • One-to-many: A single message can be delivered to multiple subscribers
  • Topic-based: Messages are organized by subject rather than specific recipients
  • Asynchronous: Publishers and subscribers operate independently
  • Scalable: New subscribers can be added without affecting publishers

When to Use Publish-Subscribe

Pub/sub is ideal for scenarios where:

  • Multiple systems need the same information
  • Publishers shouldn't need to know about all receivers
  • Message delivery shouldn't block the sender
  • Systems need to be loosely coupled
  • Message filtering is needed based on content or type
  • New subscribers may be added over time

Key Components of Pub/Sub Architecture

Publishers

Sources that generate messages:

  • Message creation: Generate data to share with other systems
  • Topic selection: Determine which topic(s) match the message
  • Message formatting: Structure data according to agreed formats
  • Publishing action: Send messages to the message broker

Topics

Categories or channels for message organization:

  • Subject-based: Organized by content type or domain
  • Hierarchical structure: Often organized in dot-notation (e.g., orders.new, orders.updated)
  • Access control: Can define who can publish/subscribe
  • Persistence options: How long messages are retained

Subscribers

Consumers that receive messages from topics they've subscribed to:

  • Subscription management: Register interest in specific topics
  • Message filtering: Optionally filter messages within topics
  • Message handling: Process incoming messages
  • Acknowledgment: Confirm message receipt when required

Message Broker

Central component that manages message delivery:

  • Queue management: Store messages until delivery
  • Routing: Deliver messages to appropriate subscribers
  • Filtering: Apply topic and content filters
  • Persistence: Optionally store messages for durability

FileMaker Implementation Approaches

While FileMaker doesn't include native pub/sub capabilities, several approaches can implement this pattern:

Simulated Pub/Sub with FileMaker Tables

Use FileMaker tables to simulate pub/sub messaging:

# Publisher script
# Publish a message to a topic
Set Variable [$topic; Value: "customer.updated"]
Set Variable [$messageData; Value: JSONSetElement("{}";
  ["customer_id"; $customerID; JSONString];
  ["modified_fields"; $modifiedFields; JSONArray];
  ["timestamp"; Get(CurrentTimestamp); JSONString]
)]

# Write to message queue table
New Record/Request [Messages]
Set Field [Messages::topic; $topic]
Set Field [Messages::message_data; $messageData]
Set Field [Messages::published_timestamp; Get(CurrentTimestamp)]
Set Field [Messages::status; "pending"]
Commit Records/Requests
# Subscriber script
# Process messages for subscribed topics
Set Variable [$topics; Value: "customer.updated¶inventory.changed"]

# Find pending messages for these topics
Enter Find Mode []
Set Field [Messages::topic; $topics]
Set Field [Messages::status; "pending"]
Perform Find []

# Process each message
Go to Record/Request/Page [First]
Loop
  # Process the current message based on topic
  Set Variable [$currentTopic; Value: Messages::topic]
  Set Variable [$messageData; Value: Messages::message_data]

  Case
    When [$currentTopic = "customer.updated"]
      Perform Script ["Process Customer Update"; Parameter: $messageData]
    When [$currentTopic = "inventory.changed"]
      Perform Script ["Process Inventory Change"; Parameter: $messageData]
  End Case

  # Mark as processed
  Set Field [Messages::status; "processed"]
  Set Field [Messages::processed_timestamp; Get(CurrentTimestamp)]

  Go to Record/Request/Page [Next; Exit after last: On]
End Loop

External Message Broker Integration

Connect FileMaker to external pub/sub systems:

# Publish to external message broker (e.g., RabbitMQ)
Set Variable [$url; Value: "https://message-broker.example.com/api/publish"]
Set Variable [$payload; Value: JSONSetElement("{}";
  ["topic"; "inventory.updated"; JSONString];
  ["message"; $messageData; JSONObject]
)]
Set Variable [$options; Value: "-X POST -H \"Content-Type: application/json\" -H \"Authorization: Bearer " & $token & "\" --data " & Quote($payload)]

Insert From URL [Select; $result; $url; cURL options: $options]

Plugin-Based Approach

Use FileMaker plugins that provide pub/sub capabilities:

# Using a plugin for MQTT pub/sub (example with MBS Plugin)
# Subscribe to a topic
Set Variable [$mqtt; Value: MBS("MQTT.New")]
Set Variable [$result; Value: MBS("MQTT.Connect"; $mqtt; "mqtt.example.com"; 1883)]
Set Variable [$result; Value: MBS("MQTT.Subscribe"; $mqtt; "customer/+/status")]
Set Variable [$result; Value: MBS("MQTT.SetMessageCallback"; $mqtt; "MQTT_MessageReceived")]

# Publish to a topic
Set Variable [$topic; Value: "inventory/products/1234"]
Set Variable [$message; Value: "{\"quantity\":15,\"status\":\"in_stock\"}"]
Set Variable [$result; Value: MBS("MQTT.Publish"; $mqtt; $topic; $message)]

SimpleQ Solution

SimpleQ is a dedicated pub/sub implementation for FileMaker that provides a complete messaging queue system:

  • Ready-to-use solution: Full implementation of the pub/sub pattern
  • Lightweight design: Easy to integrate into existing FileMaker solutions
  • Multiple message types: Support for different message categories
  • Durable queues: Reliable message delivery
  • Admin interface: Monitor and manage message queues

SimpleQ handles the complexity of message queuing, allowing developers to focus on the business logic of publishers and subscribers rather than implementing queue management from scratch.

Claris Connect Implementation

Claris Connect can act as a pub/sub broker or integrate with external messaging systems:

  • Webhook triggers: Create endpoints that act as subscribers
  • Conditional flows: Route messages based on content
  • Multiple actions: Send the same data to multiple destinations
  • External messaging: Connect to services like AWS SNS, Azure Event Grid, or Google Pub/Sub

Example approach:

  1. Create a webhook-triggered flow in Claris Connect to receive messages
  2. Implement conditional logic to process messages by type/topic
  3. Configure multiple action branches to deliver to different subscribers
  4. Set up error handling and notification for failed deliveries

Common Pub/Sub Scenarios

Event Broadcasting

Notifying multiple systems of events:

  • Status changes: Product availability updates
  • System alerts: Error notifications, threshold crossings
  • Business events: New order placements, payment receipts

Data Distribution

Sharing data across multiple systems:

  • Inventory updates: Stock level changes
  • Price changes: Product price adjustments
  • Customer data: Profile updates, preference changes

System Coordination

Coordinating activities across distributed systems:

  • Workflow progression: Status changes in business processes
  • Task assignments: Routing work to appropriate handlers
  • System synchronization: Keeping distributed systems aligned

Advantages and Challenges

Advantages

  • Highly decoupled architecture
  • Excellent scalability
  • Flexible message routing
  • Easy to add new subscribers
  • Supports dynamic environments

Challenges

  • More complex infrastructure
  • Message delivery guarantees can be difficult
  • Potential message ordering issues
  • Debugging complexity
  • Topic design challenges

Best Practices

  1. Design clear topic structures: Create a logical, hierarchical topic organization
  2. Document message formats: Define standard message structures for each topic
  3. Implement message validation: Ensure messages follow defined schemas
  4. Handle duplicate messages: Design subscribers to be idempotent
  5. Monitor message flow: Implement tracking for message publishing and delivery
  6. Consider message expiration: Define time-to-live for messages when appropriate
  7. Plan for scaling: Design your system to handle increasing message volumes
  8. Implement error handling: Create dead-letter queues for failed message processing