When creating the architecture for an Internet of Things (IoT) connected product, there’s one thing that engineers often forget about: topic structure. A well thought-out and organized topic structure is key to creating the flexibility, scalability, and security needed for a successful IoT solution. To deliver these qualities in the high-level architecture phase means designing a topic structure that takes full advantage of MQTT as a protocol and that uses the IoT platform.
The problem is, many engineers set up a topic structure reactively or without much thought. They later realize that it’s not ideal—but they don’t know how to fix it. To make matters worse, best practices for creating a topic structure are hard to come by.
For Xively, we consider best practices for creating a topic structure. Our method is based on our extensive experience implementing IoT solutions with a single, centralized broker that uses the MQTT protocol. Here, in no particular order, are our top five best practices.
- Set up device-level topics: Unlike other protocols, MQTT does not require that the publisher of information is known when that information is consumed by a subscriber. This makes it the job of the payload or application to identify which device is publishing information. Therefore, at some point in creating your topic structure, it’s important to include a device identifier to show whether information is coming or going to a specific device. For example, lights is the device identifier in the following topic structure: home/mainfloor/kitchen/lights. We recommend setting up the topic structure down to the level at which you want to implement security controls (assuming you’re securing communications by channel). In the example above, this means securing to the lights, not the kitchen, but not to individual lights in the kitchen. You can count a group of devices as one device (as in the example above) and secure the group as a whole, or you can create a topic structure that extends to individual devices. For more complex devices, the structure can extend to individual components within a single device.
- Create semantic topics: Semantics are more important than the raw sensor values from a device. Here’s why. If a device has many temperature sensors but you want the average overall temperature reading, it’s important to indicate that in your topic. In other words, instead of creating a topic for each temperature reading, create a topic for the average temperature. This allows you the flexibility to change from a single temperature sensor to an array and back again without changing the client application subscribed to a temperature channel. Contrast this with adding the specific technology into the topic structure; this requires rebuilding topic structures and the applications that use them.
- Avoid creating topics on the fly: Some MQTT brokers don’t require going through a process to create a valid topic. You can publish on any string, and as long as there’s a subscriber for that string, they’ll receive the information. But therein lies the problem. If you create topic names on the fly, you need logic on the client side to guess where the information will appear and what to subscribe to. This can also lead to overlapping topics, which means the device, which may be a very constrained platform in terms of computational resources and/or bandwidth, publishes multiple times and has to communicate more than necessary.
- Make use of MQTT’s Retain and Quality of Service (QoS) levels: The “retain” functionality allows you to publish information on a topic and have it “stick” there. If you publish information with retain today and someone subscribes to the topic tomorrow, they’ll receive the information you published yesterday. Retain prevents you from having to ping a device for its current status because this information is always retained on the channel. The QoS level reflects how many times a message is sent. There are three levels. The minimal level, QoS 0, guarantees a best-effort delivery. The message is sent only once and no acknowledgement is sent in return. QoS 1 guarantees that the message will be received at least once, but it could be received multiple times, since the message is resent until it is acknowledged. QoS 2 guarantees that the message is received once and only once. Making full use of these levels will slim down application code and create a simpler solution for connected products with intermittent connectivity.
- Don’t treat MQTT like it’s HTTP: MQTT is very different from HTTP and should be used accordingly. Don’t assume you can send a request and get a response in MQTT as you do in HTTP. Not only does request/response not exist in MQTT, but you shouldn’t be using these types of commands at all. If your solution requires request/response, then it might be time to rethink the architecture. This is important to keep in mind when naming topics. If you do require request/response functionality, consider using HTTP for that portion of your IoT solution.
Following these best practices for creating your topic structure will help ensure that your IoT solution remains flexible, scalable, and secure as it evolves to meet changing business demands.