Skip to main content
Docs: ApiGear Core

ApiGear MQTT Topic Mapping

This is the wire specification for running ObjectAPI interfaces over MQTT v5. It defines how an interface's members map to MQTT topics and payloads. The mapping is transport-level and language-independent — a service generated by any template interoperates with a client generated by any other.

Formal document: ApiGear MQTT Spec v0.1 (PDF).

Topic structure

All topics are built from the module name, interface name, a verb, and the member name, separated by /:

{moduleName}/{interfaceName}/{verb}/{memberName}
VerbMemberDirectionPurpose
rpcoperationclient → serviceInvoke an operation (request)
sigsignalservice → clientSignal broadcast
proppropertyservice → clientProperty value notification (retained)
setpropertyclient → serviceProperty change request

Using an interface Hello in module io.world as an example:

DirectionTopicPurpose
Client → Serviceio.world/Hello/set/lastSet property request
Service → Clientio.world/Hello/prop/lastProperty change notification (retained)
Client → Serviceio.world/Hello/rpc/sayOperation invocation
Service → Clientio.world/Hello/rpc/say/{clientId}/resultOperation reply (per-client)
Service → Clientio.world/Hello/sig/justSaidSignal broadcast

Operations (request / response)

Operations use a request topic and a per-client response topic.

Request — the client publishes; the service subscribes:

Topic: {moduleName}/{interfaceName}/rpc/{functionName}
Content: JSON array of the operation arguments, e.g. [42]
MQTT v5: CorrelationData = unique call id (UUID); ResponseTopic = the reply topic below

Response — the service publishes to the caller's ResponseTopic; that client subscribes:

Topic: {moduleName}/{interfaceName}/rpc/{functionName}/{UniqueClientID}/result
Content: JSON-encoded return value
MQTT v5: CorrelationData = the same call id, echoed back unchanged

The CorrelationData property carries the unique call id as opaque bytes, which the service echoes back on the reply. This lets multiple clients invoke the same operation concurrently without their replies colliding — each client matches the echoed id to the call it made.

Internal (non-API) operations

Operations not declared in the API (template-internal helpers) use the same rpc verb with an underscore prefix on the function name, so they never clash with generated operations:

{moduleName}/{interfaceName}/rpc/_{functionName}

Signals

The service publishes; clients subscribe:

Topic: {moduleName}/{interfaceName}/sig/{signalName}
Content: JSON array of the signal arguments

Properties

Property handling is split into a change request and a value notification:

Set (change request) — the client publishes a desired value; the service subscribes:

Topic: {moduleName}/{interfaceName}/set/{propertyName}
Content: JSON-encoded property value

Notify (value) — the service publishes the current value; clients subscribe:

Topic: {moduleName}/{interfaceName}/prop/{propertyName}
Content: JSON-encoded property value
Retained state

Property value notifications are published with retain = true. A newly-subscribing client therefore receives the current value immediately on subscription — no separate handshake is needed.

Payloads & QoS

  • Payloads are JSON-encoded. Operation requests carry an args-only array (e.g. [42]); the call id rides on the MQTT v5 CorrelationData property rather than inside the payload.
  • Property values and signal argument arrays are plain JSON.
  • Subscribe/publish use QoS 1 (at-least-once delivery) by default.

MQTT v3.1.1 fallback

MQTT 3.1.1 has no user properties, so the v3 mapping moves the version into the topic and embeds the correlation data and response topic inside the payload:

Request: {moduleName}/{interfaceName}/rpc/v3/{functionName}
Content: Data { correlationData (call id) + ResponseTopic }
Response: {moduleName}/{interfaceName}/rpc/v3/{functionName}/{UniqueClientID}/result
Content: Data { correlationData (call id) }

Prefer MQTT v5 where the broker supports it; it keeps payloads clean and uses native correlation.

Implemented by

Related: ApiGear over NATS · ObjectLink · Protocol Mappings