0

What's best practice for separating the declaration of messages used in services in (Go-specific) Protocol Buffers? The context is a large application with multiple gRPC services. Some messages are used in multiple services. The thought was to divide the definitions of message and services, like this (simplified a bit):

airline/pb/airline_messages.proto:

syntax = "proto3";
option go_package = "github.com/example.com/example-repo/airline/pb";

message Airline {
    string code = 1;
    string name = 2;
    string country = 3;
}

airline/pb/airline_services.proto:

syntax = "proto3";
option go_package = "github.com/example.com/example-repo/airline/pb";
import "airline/pb/airline_messages.proto"

service AirlineService {
    rpc GetAirline(string) returns (Airline) {}
    rpc GetAirlines(GetAirlinesRequest) returns (repeated Airline) {}
}

message GetAirlinesRequest {
    int max = 1;
    string country = 2;
    string pattern = 3;
    string sortby = 4;
}

I'm calling protoc like this:

protoc --go_out=. \
   --go_opt=paths=source_relative \
   --go-grpc_out=. \
   --go-grpc_opt=paths=source_relative \
   --proto_path=. \
   --proto_path=../../ airline_services.proto

This doesn't work because Airline isn't defined. Invoking it like this:

protoc ... airline_services.proto airline_messages.proto

generates an error message the Airline is multiply defined. Doing this:

protoc ... airline_messages.proto
protoc ... airline_services.proto

just overwrites the Go files and is equivalent to just compiling airline_services.proto.

What's best practice for being able to reuse message definitions in multiple services?

Scott Deerwester
  • 3,503
  • 4
  • 33
  • 56

1 Answers1

0

Not sure if it helps or if you are using a different version of the Go generator.

I have multiple *.proto files in one directory. Some of them import others:

A part of device.proto importing status.proto:

syntax = "proto3";

package somePackage;

import "status.proto";

option go_package = "goPackageName";

service Device {
    rpc GetStatus (GetStatusRequest) returns (Status) {}
}

message GetStatusRequest {
    // ...
}

with status.proto containing the Status message:

syntax = "proto3";

package somePackage;

option go_package = "goPackageName";

message Status {
    int32 customer = 1;
    string device_id = 2;
    // ...
}

I generate the Go code with:

protoc --go_out=plugins=grpc:. --go_opt=paths=source_relative *.proto

Note: I'm still using the old Go protobuf github.com/golang/protobuf.

TehSphinX
  • 6,536
  • 1
  • 24
  • 34