NATS subjects are not just strings; they’re hierarchical paths that unlock powerful messaging patterns.
Let’s see NATS in action. Imagine a simple IoT sensor network. We have temperature sensors in different rooms of a building.
// Publisher sending a temperature reading
nats_cli pub "sensor.room.kitchen.temp" "22.5"
// Publisher sending another reading
nats_cli pub "sensor.room.bedroom.temp" "21.0"
// Subscriber listening to all temperature sensors
nats_cli sub "sensor.room.*.temp"
When the nats_cli sub "sensor.room.*.temp" command runs, it receives both "22.5" (from sensor.room.kitchen.temp) and "21.0" (from sensor.room.bedroom.temp). The * acts as a wildcard, matching any single token in that position of the subject.
NATS subjects are structured as dot-separated hierarchical paths, similar to file system paths. Each dot separates a level in the hierarchy. This structure allows for sophisticated routing and filtering of messages. When a publisher sends a message to a subject, NATS delivers it to all subscribers whose subscriptions match that subject.
The core of NATS subject design lies in its two primary wildcard characters: * (wildcard) and > (wildcard/catch-all).
The * wildcard matches exactly one token in a subject. A token is any sequence of characters between dots. For example, in the subject sensor.room.kitchen.temp, sensor, room, kitchen, and temp are all tokens. If a subscriber subscribes to sensor.room.*.temp, it will receive messages sent to sensor.room.kitchen.temp and sensor.room.bedroom.temp, but not sensor.room.livingroom.thermostat.
The > wildcard, also known as the "full wildcard" or "catch-all," matches one or more tokens at the end of a subject. It must be the last token in a subscription. For example, if a subscriber subscribes to sensor.room.>.
// Subscriber listening to all sensor data from any room
nats_cli sub "sensor.room.>"
This subscriber would receive messages for sensor.room.kitchen.temp, sensor.room.bedroom.temp, sensor.room.livingroom.humidity, and so on. It effectively subscribes to everything under the sensor.room branch of the hierarchy.
A common mistake is to think of > as a wildcard that can appear anywhere. It must be the last token in a subject and will match everything from that point onwards. A subscription like sensor.room.>.temp is invalid.
Let’s consider a more complex scenario with fleet management.
// Publisher: Vehicle 123 reporting its GPS location
nats_cli pub "fleet.vehicle.123.gps" "{\"lat\": 34.0522, \"lon\": -118.2437}"
// Publisher: Vehicle 456 reporting its engine status
nats_cli pub "fleet.vehicle.456.engine" "OK"
// Subscriber: All GPS data for all vehicles
nats_cli sub "fleet.vehicle.*.gps"
// Subscriber: All data for vehicle 123
nats_cli sub "fleet.vehicle.123.>"
// Subscriber: All fleet data
nats_cli sub "fleet.>"
In this example:
fleet.vehicle.*.gpsmatches any GPS update from any vehicle.fleet.vehicle.123.>matches any update from vehicle 123, regardless of the data type (GPS, engine, speed, etc.).fleet.>matches any message published under thefleethierarchy.
The power of this hierarchical design is that NATS can efficiently route messages without needing to inspect the message payload. The matching is done at the NATS server level based on the subject string. This means that even with millions of messages and subscriptions, NATS can maintain high throughput and low latency.
When designing your subjects, think about the natural hierarchy of your data and the types of queries you’ll want to make. A good practice is to place more specific information towards the end of the subject and more general information at the beginning. For instance, orders.us.california.processed is more specific than orders.us.processed.
The > wildcard, when used as a subscription, doesn’t just match any single token; it matches any sequence of tokens that follow the part of the subject before the >. So, orders.us.> will match orders.us.california and orders.us.california.processed and orders.us.ny.shipped, etc. It’s a powerful way to subscribe to entire branches of your subject tree.
The next step in mastering NATS subjects is understanding how to combine wildcards for more granular subscriptions.