NATS Logo by Example

Protobuf for Message Payloads in Messaging

NATS message payloads are byte slices, so any kind of serialization strategy can be applied. This example shows a simple way to define message types using the Protocol Buffers IDL, generate code for the target language, and then use it with NATS.

If you are new to Protobuf, you can get started using one of the official tutorials.

The protobuf file for example looks as follows:

  syntax = "proto3";

  option go_package = ".;main";

  package main;

  message GreetRequest {
    string name = 1;
  }

  message GreetReply {
    string text = 1;
  }

Click the link to the example’s source code to view the generated code.

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

Code

package main


import (
	"fmt"
	"os"
	"time"


	"github.com/nats-io/nats.go"
	"google.golang.org/protobuf/proto"
)


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 an async subscription that will respond to greet requests. This will unmarshal the request and reply with a new message.

	nc.Subscribe("greet", func(msg *nats.Msg) {
		var req GreetRequest
		proto.Unmarshal(msg.Data, &req)


		rep := GreetReply{
			Text: fmt.Sprintf("hello %q!", req.Name),
		}
		data, _ := proto.Marshal(&rep)
		msg.Respond(data)
	})

Allocate the request type which is a generate protobuf type. and Marshal it using the proto package.

	req := GreetRequest{
		Name: "joe",
	}
	data, _ := proto.Marshal(&req)

Messages are published to subjects. Although there are no subscribers, this will be published successfully.

	msg, _ := nc.Request("greet", data, time.Second)


	var rep GreetReply
	proto.Unmarshal(msg.Data, &rep)


	fmt.Printf("reply: %s\n", rep.Text)
}

Output

reply: hello "joe"!

Recording

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