Basics of Protocol Buffers 3 – Part 2

This post explains basics of protocol buffers 3 part 2. It will specifically focus on how to do the followings.
1. multiple messages in a same file
2. nested messages
3. imports
4. packages

If you would like to read part 1, please read this post.

Multiple messages in a same file

You can have multiple messages in a same .proto file. Here is an example.
All you need to do is to define those messages and reference properly.

syntax = "proto3";

message Person {
    string first_name = 1;
    string last_name = 2;
    Address address = 3;
}

message Address {
    string street = 1;
    string city = 2;
    string zip_code = 3;
}

Nested Messages

You can nest messages depending on your design. You might want to nest messages to avoid naming conflicts (you can also use packages for this) or enforce some level of locality for that type. And you can nest types as deep as you want. Let’s take a look at an example code.

syntax = "proto3";

message Person {
    string first_name = 1;
    string last_name = 2;
    
    message Address {
        string street = 1;
        string city = 2;
        string zip_code = 3;
    }
    
    Address address = 3;
}

Import Messages

It is very reasonable to have messages in a different file and reuse it. This is especially the case that you need to use proto file created by another team. We have two files for the example. Please note that when you import you need to specify the folder too even if the files are in the same directory.

// this is person.proto located under "info" directory.
syntax = "proto3";

import "info/address.proto";

message Person {
    string first_name = 1;
    string last_name = 2;
    Address address = 3;
}
// this is address.proto located under "info" directory
syntax = "proto3";

message Address {
    string street = 1;
    string city = 2;
    string zip_code = 3;
}

Packages

It is important to define the packages where your protocol buffer messages live for the following reasons.
1. The file will be placed at the package you specified when you compile the code
2. It will prevent name conflicts between messages

Packages will assure all the different languages compile correctly from .proto files. When you import package proto, make sure you specify package in front of the imported messages. Let’s take a look at the example below.

// city.proto located under "info" directory
syntax = "proto3";

package city;

message City {
    string name = 1;
    string country_code = 2;
}
// address.proto located under "info" directory
syntax = "proto3";

package address;

import "info/city.proto";

message Address {
    string street = 1;
    city.City city = 2;
    string zip_code = 3;
}
// person.proto located under "info" directory
syntax = "proto3";

package person;

import "info/address.proto";

message Person {
    string first_name = 1;
    string last_name = 2;
    address.Address address = 3;
}

Conclusion

We have taken a look at simple but pretty useful features of protocol buffers. Next post will explain how to compile and use in python/go language.