NATS Logo by Example

JSON for Message Payloads in Messaging

The basic structure of a NATS message modeled in the client libraries includes the subject the message was published to, the application-defined payload, and an optional set of headers (for requests, there is also a reply-to subject). The payload is a sequence of bytes, so it is up to the application to define how to serialize and deserialize the payload.

JSON is ubiquitous and simple data-interchange format that is supported in virtually all programming languages. This example demonstrates how to serialize and deserialize a message payload using a JSON library.

CLI Go Python JavaScript Rust C# Java Ruby Elixir Crystal C
Jump to the output or the recording
$ nbe run messaging/json/go
View the source code or learn how to run this example yourself

Code

package main


import (
	"encoding/json"
	"fmt"
	"os"
	"time"


	"github.com/nats-io/nats.go"
)


type payload struct {
	Foo string `json:"foo"`
	Bar int    `json:"bar"`
}


func main() {

Use the env variable if running in the container, otherwise use the default.

	url := os.Getenv("NATS_URL")
	if url == "" {
		url = nats.DefaultURL
	}

Create an unauthenticated connection to NATS.

	nc, _ := nats.Connect(url)
	defer nc.Drain()

Create a subscription that receives two messages. One message will contain a valid serialized payload and the other will not.

	sub, _ := nc.SubscribeSync("foo")
	sub.AutoUnsubscribe(2)

Construct a Payload value and serialize it.

	p := &payload{
		Foo: "bar",
		Bar: 27}


	p_json, _ := json.Marshal(p)

Publish the serialized payload.

	nc.Publish("foo", p_json)
	nc.Publish("foo", []byte("not json"))

Loop through the expected messages and attempt to deserialize the payload into a payload value. If deserialization into this type fails, alternate handling can be performed, either discarding or attempting to deserialize in a more general type (such as the empty interface): var dat map[string]interface{}

	var dat payload
	for {
		msg, err := sub.NextMsg(time.Second)
		if err != nil {
			break
		}


		err = json.Unmarshal(msg.Data, &dat)
		if err != nil {
			fmt.Printf("received invalid JSON payload: %s\n", msg.Data)
		} else {
			fmt.Printf("received valid JSON payload: %+v\n", dat)
		}
	}


}

Output

received valid JSON payload: {Foo:bar Bar:27}
received invalid JSON payload: not json

Recording

Note, playback is half speed to make it a bit easier to follow.