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# .NET V2 Java Ruby Elixir Crystal C
Jump to the output or the recording
$ nbe run messaging/json/crystal
View the source code or learn how to run this example yourself


require "nats"
require "json"

Use the JSON::Serializable mixin to be able to serialize and deserialize a struct we define.

struct Payload
  include JSON::Serializable

  getter foo : String
  getter bar : UInt8

  def initialize(@foo, @bar)

Get the NATS_URL from the environment or fallback to the default. This can be a comma-separated string. We convert it to an Array(URI) to pass to the NATS client.

servers = ENV.fetch("NATS_URL", "nats://localhost:4222")
  .map { |url| URI.parse(url) }

Create a client connection to an available NATS server.

nats =

When the program exits, we close the NATS client which waits for any pending messages (published or in a subscription) to be flushed.

at_exit { nats.close }

Create a subscription. We will receive both valid and invalid JSON here, so we rescue the JSON::ParseException.

nats.subscribe "foo" do |msg|
  json =
  payload = Payload.from_json(json)

  puts "received valid JSON: #{payload}"
rescue JSON::ParseException
  puts "received invalid JSON: #{json}"

Construct and serialize a Payload struct.

payload = "bar", bar: 27).to_json

Publish the serialized payload

nats.publish "foo", payload
nats.publish "foo", "not json"


received valid JSON: Payload(@foo="bar", @bar=27)
received invalid JSON: not json


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