Skip to content

Cross-Protocol Routing

Cross-protocol routing lets producers and consumers using different protocols communicate directly through the same FlowMQ routing core.

FlowMQ's core messaging model is protocol-independent: producers publish messages with topics, destinations bind to topic filters, and consumers receive messages from destinations. See Messaging Model for the core concepts.

This page focuses on how that model is exposed across protocols.

How It Works

When a client publishes through a protocol endpoint, FlowMQ associates the protocol message with an internal routing topic. This topic is the routing address used by FlowMQ's protocol-independent routing engine.

  1. A producer publishes using its protocol-native target.
  2. FlowMQ associates the message with an internal routing topic derived from that target.
  3. FlowMQ routes the message to destinations whose filters match the topic.
  4. Consumers receive the message from those destinations using the protocol interface they connect with.

The producer does not need to know which protocol the consumer uses. The consumer does not need to know which protocol produced the message.

MQTT Mapping

MQTT topics already use the same hierarchical shape as FlowMQ topics, so the publish topic maps directly to the internal routing topic.

MQTT conceptExampleFlowMQ model
Publish topicsensors/factory-1/temperatureInternal routing topic sensors/factory-1/temperature
Subscribe filtersensors/#Subscription filter sensors/#

Kafka Mapping

Kafka exposes writes and reads through Kafka topics, partitions, and offsets. FlowMQ maps Kafka records onto the core model by deriving an internal routing topic from the Kafka topic name, then appending matching messages to streams.

Publishing

When a Kafka producer sends a record, FlowMQ derives the internal routing topic from the Kafka topic name. By convention, dot-separated Kafka topic names map to slash-separated internal routing topics. The record key, value, headers, and timestamp are preserved as message data or metadata, but they do not participate in topic derivation.

Kafka publish targetFlowMQ internal routing topic
Topic orders.createdorders/created
Topic ordersorders

For example, a Kafka record produced to Kafka topic a.b.c is routed as a message with internal topic a/b/c. An MQTT client subscribed to a/b/c can receive that message directly.

Streams

A FlowMQ stream is exposed to Kafka clients as a Kafka topic with the same name. By default, that stream binds to the internal routing topic derived from the Kafka topic name, so records produced through Kafka are appended to the stream that Kafka consumers read.

FlowMQ modelKafka protocol view
Stream orders.createdKafka topic orders.created
Topic filter orders/createdDefault binding for stream orders.created
Stream partition 0Kafka partition 0
Offset 42 in that stream partitionKafka offset 42

The same binding also enables other protocols to write into Kafka-visible streams. For example, an MQTT message published to orders/created matches the default binding for stream orders.created, so Kafka consumers subscribed to topic orders.created can read it.

A stream can also have additional bindings to more topic filters, allowing the same Kafka-visible stream to collect messages from multiple internal routing topics. See Streaming to learn more.

AMQP Mapping

AMQP exposes routing through exchanges, routing keys, queues, and bindings. FlowMQ maps AMQP publish operations and queue bindings onto the core model by deriving internal routing topics and matching those topics against queue bindings.

Publishing

When an AMQP client publishes a message, FlowMQ derives the internal routing topic from the AMQP exchange, routing_key, and exchange type. AMQP message properties and headers are preserved as message metadata, but they do not participate in topic derivation.

For direct and topic exchanges, FlowMQ combines the exchange name with the routing key. Dot-separated routing key words map to slash-separated topic levels.

AMQP publish targetFlowMQ internal routing topic
Exchange orders, routing key created.usorders/created/us
Exchange orders, routing key createdorders/created

For fanout exchanges, the routing key is ignored as in AMQP. FlowMQ uses the exchange name as the internal routing topic:

AMQP publish targetFlowMQ internal routing topic
Fanout exchange notifications, any routing keynotifications

The AMQP default exchange (exchange="") keeps its AMQP direct-to-queue behavior. Its routing key identifies the target queue, so FlowMQ treats it as direct delivery to the queue with that name instead of exposing it as a general cross-protocol topic.

Queues and Bindings

An AMQP queue maps directly to a FlowMQ queue destination:

AMQP conceptFlowMQ model
Queue order-processingQueue destination order-processing

AMQP queue bindings define how that queue matches derived internal routing topics.

For direct exchanges, the binding key is an exact routing key. AMQP wildcard characters have no wildcard meaning in direct exchanges.

AMQP bindingFlowMQ matching rule
Exchange orders, binding key created.usMatch internal topic orders/created/us

For topic exchanges, AMQP topic binding keys are compiled into FlowMQ topic filters when they can be represented by FlowMQ's filter syntax.

AMQP topic bindingFlowMQ queue binding filter
Exchange orders, binding key created.*orders/created/+
Exchange orders, binding key created.#orders/created/#

FlowMQ's general topic filter model uses MQTT-style wildcards: + matches one level, and # matches zero or more levels at the end of a filter. AMQP topic exchanges also allow # in positions that cannot be represented as a FlowMQ topic filter, such as #.created or created.#.high.

FlowMQ still supports those AMQP-native bindings for AMQP queues. They are evaluated with AMQP topic-exchange matching rules against the message's derived routing address, but they are not exposed as FlowMQ topic filters.

For example, an AMQP message published to topic exchange orders with routing key created.us is routed as a message with internal topic orders/created/us. An AMQP queue bound to exchange orders with topic binding key created.* can receive the message because that binding compiles to FlowMQ filter orders/created/+. An MQTT client subscribed to orders/created/+ can also receive this message directly.

Routing Across Protocols

Cross-protocol routing works because messages from different protocols are associated with internal topics in the same routing model. After a message has an internal topic, FlowMQ routes it without depending on the protocol that produced it.

If the internal topic matches a destination's filter, or an AMQP-native queue binding evaluated by the AMQP adapter, the message is delivered to that destination. Consumers can then receive the message through any protocol interface that exposes that destination or subscription.

Common patterns include:

  • Device telemetry published through a lightweight protocol and stored in a stream for processing.
  • Application events published by a service and pushed to online clients through subscriptions.
  • Jobs published by one client and consumed from a queue by workers using another protocol.

Because routing is handled by FlowMQ's core, there is no external bridge between protocol-specific brokers.

MQTT to Kafka Example

An MQTT device publishes telemetry to:

text
sensors/factory-1/temperature

A stream named sensor.telemetry is bound to:

text
sensors/#

FlowMQ routes the message to the stream because the MQTT publish topic maps to internal topic sensors/factory-1/temperature, which matches the stream filter sensors/#.

A Kafka consumer reads from the stream through the Kafka protocol:

text
sensor.telemetry

The MQTT device does not need to know that the message is stored in a stream or consumed by a Kafka client.

Kafka to MQTT Example

A backend service sends a device control command through Kafka:

text
devices.vehicle-42.commands

FlowMQ maps that Kafka topic to the internal topic:

text
devices/vehicle-42/commands

The device is connected through MQTT and subscribes to:

text
devices/vehicle-42/commands

FlowMQ routes the command to the MQTT subscription because devices/vehicle-42/commands matches the device's subscription. The backend service can use a Kafka client only and does not need an MQTT client to communicate with devices.

Why This Matters

Cross-protocol routing helps you:

  • Let each application use its native protocol interface while still exchanging messages through FlowMQ.
  • Avoid deploying separate message brokers for different protocols.
  • Replace protocol-specific bridges with native routing inside one broker.
  • Share data between device, backend, and analytics systems without duplicating ingestion pipelines.
  • Preserve protocol-specific client behavior while routing messages through the same internal model.