MQTT Messaging

Spin provides an experimental interface for you to send messages using the MQTT protocol.

Why do I need a Spin interface? Why can't I just use my language's MQTT library?

Few MQTT libraries have been updated to work over the WASI 0.2 sockets interface. The Spin interface means Wasm modules can bypass this limitation by asking Spin to make the MQTT connection on their behalf.

Want to receive MQTT messages? Use the MQTT trigger to handle messages in your Spin application.

Sending MQTT Messages From Applications

The Spin SDK surfaces the Spin MQTT interface to your language. The set of operations defined in Spin’s API is as follows:

OperationParametersReturnsBehavior
openaddress, username, password, keep-aliveconnection resourceOpens a connection to the specified MQTT server. The host must be listed in allowed_outbound_hosts. Other operations must be called through a connection.
publishtopic, payload, QoS-Publishes the payload (a binary blob) as a message to the specified topic.

The exact detail of calling these operations from your application depends on your language:

Want to go straight to the reference documentation? Find it here.

MQTT functions are available in the spin_sdk::mqtt module.

To access an MQTT server, use the Connection::open function.

let connection = spin_sdk::mqtt::Connection::open(&address, &username, &password, keep_alive_secs)?;

You can then call the Connection::publish function to send MQTT messages:

let cat_picture: Vec<u8> = request.body().to_vec();
connection.publish("pets", &cat_picture, spin_sdk::mqtt::Qos::AtLeastOnce)?;

For full details of the MQTT API, see the Spin SDK reference documentation;

You can find a complete Rust code example for using outbound MQTT from an HTTP component in the Spin Rust SDK repository on GitHub.

Want to go straight to the reference documentation? Find it here.

To access an MQTT server, use the Mqtt.open function.

let connection = Mqtt.open(address, username, password, keepAliveSecs);

You can then call the publish method on the connection to send MQTT messages:

let catPicture = new Uint8Array(await req.arraybuffer());
connection.publish("pets", catPicture, QoS.AtleastOnce);

For full details of the MQTT API, see the Spin SDK reference documentation

You can find a complete Rust code example for using outbound MQTT from an HTTP component in the Spin Rust SDK repository on GitHub.

MQTT is not available in the current version of the Python SDK.

MQTT is not available in the current version of the Go SDK.

Granting Network Permissions to Components

By default, Spin components are not allowed to make outgoing network requests, including MQTT. This follows the general Wasm rule that modules must be explicitly granted capabilities, which is important to sandboxing. To grant a component permission to make network requests to a particular host, use the allowed_outbound_hosts field in the component manifest, specifying the host and allowed port:

[component.uses-mqtt]
allowed_outbound_hosts = ["mqtt://messaging.example.com:1883"]

Configuration-Based Permissions

You can use application variables in the allowed_outbound_hosts field. However, this feature is not yet available on Fermyon Cloud.

Known Issues

The MQTT API is experimental and subject to change. The following issues are known:

  • The MQTT sender interface in the current version of Spin is known to occasionally drop errors, especially if under load. A fix is in progress.