Serializing protobuf objects using protoc

Problem

We want to send some protobuf serialized data to an implemented RPC API endpoint for testing.

Note: This is especially helpful if you work with Twirp and code in Python since the code generator does not yield a JSON Protobuf client.

Solution

You can use the protoc command to generate binary data and then pass them to curl (see 1 and 2).

Switch to the location in the Gopath which contains your api.proto file:

cd $GOPATH/src/git.example.com/my-project/

Assuming a message type with fully qualified name example.Example

package example;

message Example {
  string data = 1;
}

we can generate a protobuf serialization by running

echo 'data: "bla"' \
| protoc --proto-path $GOPATH/src/git.example.com/my-project --encode example.Example api.proto

Piping this into curl call which expects binary data on STDIN lets us send protobuf serialized binary data to the target URL; e.g. for localhost:8000/twirp/example.MyRPCService/MyEndpoint

echo 'data: "bla"' \
| protoc --proto-path $GOPATH/src/git.example.com/my-project --encode example.Example api.proto
| curl -H "Content-Type: application/protobuf" --data-binary @- localhost:8000/twirp/example.MyRPCService/MyEndpoint

Note: The input string for the encoder has a unique notation which is similar but not identical to JSON in that

  • double quotes around object keys are omitted,
  • object key-value pairs are separated with semicolons (“;”), and
  • curly braces for the top-level object are omitted.

Otherwise, the serialization rules are the same as given in the Protobuf language guide (e.g. messages map to objects, …).

Sources