Skip to main content
  1. Notes/

Protocol Buffers

  • 2 spaces, 80 characters per line, lower_snake_case.proto
  • If a file is in my/package/, then the package name should be my.package

Code Example #

syntax = "proto3";
package test;

import "myproject/other.proto";

enum Foo {
  // The zero value enum should have the suffix UNSPECIFIED.
  FOO_UNSPECIFIED = 0;
  FOO_FIRST_VALUE = 1;
  FOO_SECOND_VALUE = 2;
}

message SongServerRequest {
  required string song_name = 1;
  repeated string keys = 1;
}

service SearchService {
  rpc Search (SearchRequest) returns (SearchResponse);
}

Compilation #

# Protocol Buffers
protoc --proto_path=IMPORT_PATH --go_out=DST_DIR path/to/file.proto
# Protocol Buffers with gRPC
protoc --proto_path=IMPORT_PATH --go_out=plugins=grpc:DST_DIR path/to/file.proto
  • --proto_path - for resolving import directives (default is current directory) In general you should set the --proto_path flag to the root of your project and use fully qualified names for all imports.

Message #

  • every field has an unique number, don’t change any of the existing numbers
  • 1 - 15 stored in 1 byte - frequently occurring message elements
  • 16 - 2047 stored in 2 bytes
  • reserved 19000 through 19999

Fields #

  • singular - default, zero or one times
  • repeated - field repeated any number of times, order is perserved, use pluralized name
  • previously deleted/commented fields can be reused, can be prohibited by reserved field
  • use song_name1 instead of song_name_1
message Foo {
  reserved 2, 15, 9 to 11;
  reserved "foo", "bar";
}

Scalar Types #

.protoGoNotes
doublefloat64
floatfloat32
int32int32variable-length encoding, inefficient for negative numbers
int64int64variable-length encoding, inefficient for negative numbers
uint32uint32variable-length encoding
uint64uint64variable-length encoding
sint32int32variable-length encoding, signed
sint64int64variable-length encoding, signed
fixed32uint324 bytes, efficient for numbers greater than 228
fixed64uint648 bytes, efficient for numbers greater than 256
sfixed32int324 bytes
sfixed64int648 bytes
boolbool
stringstringUTF-8 or ASCII, cannot be longer than 232
bytes[]bytesequence of bytes no longer than 232

Enums #

  • every enum definition must contain a constant that maps to zero as its first element
  • range of positive 32-bit integer
  • can use reserved field
enum Foo {
  reserved 2, 15, 9 to 11, 40 to max;
  reserved "FOO", "BAR";
}

Imports #

// new.proto
// All definitions are moved here

// old.proto
// This is the proto that all clients are importing.
import public "new.proto";
import "other.proto";

// client.proto
import "old.proto";
// You use definitions from old.proto and new.proto, but not other.proto

Any #

  • lets you use messages as embedded types without having their definition
  • serialized as bytes
  • along with a URL that acts as a globally unique identifier for and resolves to that message’s type
  • can be used by importing google/protobuf/any.proto
import "google/protobuf/any.proto";

message ErrorStatus {
  string message = 1;
  repeated google.protobuf.Any details = 2;
}

Oneof #

  • like union in C
  • fields cannot be repeated
  • oneof cannot be repeated
message SampleMessage {
  oneof test_oneof {
    string name = 4;
    SubMessage sub_message = 9;
  }
}

Map #

  • key_type - integral or string type (no floats, bytes or enums)
  • value_type - any type except another map
  • fields cannot be repeated
map<key_type, value_type> map_field = N;