首页 > 解决方案 > 如何为不同的 gRPC 端点重用 proto-buffer 消息?

问题描述

我有一个使用原始缓冲区(准确地说是 Proto3)的 Go 应用程序。

该应用程序有 2 个端点,A定义B如下:

rpc A(ARequest) returns (AResponse) {
  option (google.api.http) = {
    post: "/someURLA"
    body: "*"
  };
}
rpc B(BRequest) returns (BResponse) {
  option (google.api.http) = {
    put: "/someURLB"
    body: "*"
  };
}

以下是他们使用的消息:

message ARequest {
    // Blah Blah Blah
}

message BRequest {
    // Blah Blah Blah   
}

message AResponse {
    // Blah Blah Blah
}

message BResponse {
    // Blah Blah Blah   
}

端点实际上需要相同的输入格式AB具有相同的输出格式。SoARequest等同于BRequestAResponse等同于BResponse。但是 protofile 中的这些重复定义非常浪费,并且可能会出现分歧。所以我把它改成这样:

rpc A(AOrBRequest) returns (AOrBResponse) {
  option (google.api.http) = {
    post: "/someURLA"
    body: "*"
  };
}
rpc B(AOrBRequest) returns (AOrBResponse) {
  option (google.api.http) = {
    put: "/someURLB"
    body: "*"
  };
}

message AOrBRequest {
    // Blah Blah Blah
}

message AOrBResponse {
    // Blah Blah Blah
}

但是当我这样做时,我在编译过程中遇到了这些错误:

Name of request type "AOrBRequest" should be "ARequest".
Name of response type "AOrBResponse" should be "AResponse"
Name of request type "AOrBRequest" should be "BRequest".
Name of response type "AOrBResponse" should be "BResponse"

那么如何让这两个端点对请求和响应重用相同的消息呢?

标签: goprotocol-buffers

解决方案


您可以使用import 语句来重用消息定义。

您可以通过导入其他 .proto 文件中的定义来使用它们。要导入另一个 .proto 的定义,请在文件顶部添加一个 import 语句:

import "myproject/other_protos.proto";

例如,如果您下载了 Protocol Buffers 二进制包,readme.txt存档中的内容会显示:

如果您打算使用包含的众所周知的类型,那么不要忘记将include目录的内容也复制到某处,例如复制到/usr/local/include/.

如果你已经这样做了,你现在可以导入(或重复使用,如你所说)谷歌定义的消息。

syntax = "proto3";

package mypackage;

import "google/protobuf/empty.proto";
import "google/protobuf/timestamp.proto";

service Bla {
    rpc ResetUserPW(UserEmail) returns (google.protobuf.Empty) {}
    rpc ServerTime(google.protobuf.Empty) returns (google.protobuf.Timestamp) {}
}

message UserEmail {
    string email = 1;
    CallBackUrl url = 2;
}

推荐阅读