NATS Protocol Gateway
TinyMQ v2.9.0 introduced a native, zero-dependency NATS text protocol gateway.
This allows you to use standard, highly-optimized NATS clients (nats.go, nats.py, nats.js, async-nats) to interact with TinyMQ. Because NATS uses persistent TCP connections, it completely eliminates HTTP overhead, offering significantly higher throughput for microservices.
Enabling the NATS Gateway
By default, the NATS gateway is disabled. To enable it, set the port:
TINYMQ_NATS_PORT=4222
Cross-Protocol Routing
Like MQTT, the NATS gateway is fully integrated with TinyMQ's core WAL.
Supported Commands
TinyMQ implements the core NATS text protocol specifications:
| Command | Status | Notes |
|---|---|---|
INFO | ✅ Supported | Sent by server upon connection |
CONNECT | ✅ Supported | Parses client options and auth |
PUB | ✅ Supported | Publishes message to WAL |
SUB | ✅ Supported | Registers non-destructive spy listener |
UNSUB | ✅ Supported | Removes listener |
PING / PONG | ✅ Supported | Keep-alive |
MSG | ✅ Supported | Outbound message delivery |
Authentication
If TINYMQ_API_KEY is set, NATS clients must authenticate. The gateway supports two methods during the CONNECT handshake:
auth_token: Set directly to the API key.userandpass: Thepassfield must match the API key.
Subject Translation
NATS uses specific wildcard characters for subjects. The gateway automatically translates these into TinyMQ's internal wildcard format:
| NATS Subject | TinyMQ Translation | Description |
|---|---|---|
foo.> | foo.* | Matches foo.bar, foo.baz.qux |
foo.* | foo.* | Matches foo.bar |
System Limits
The NATS gateway enforces TinyMQ's core limits:
- Max Payload: 2 MB. Larger payloads will result in an
-ERR 'Payload Too Large'response and disconnection. - Idle Timeout: 60 seconds without a PING will result in disconnection.
Code Example (Go)
package main
import (
"log"
"github.com/nats-io/nats.go"
)
func main() {
// Connect to TinyMQ's NATS Gateway
nc, err := nats.Connect("nats://localhost:4222", nats.Token("your_api_key"))
if err != nil {
log.Fatal(err)
}
defer nc.Close()
// Subscribe
nc.Subscribe("orders.>", func(m *nats.Msg) {
log.Printf("Received: %s on %s", string(m.Data), m.Subject)
})
// Publish
nc.Publish("orders.created", []byte(`{"id": 123}`))
select {} // Block forever
}