grpc Protobuff 3嵌套消息定义

时间:2019-02-13 16:21:45

标签: protocol-buffers grpc

我想以这种嵌套方式定义我的消息:

FooRequest

  • messageId
  • correlationId
  • moreFields
  • 有效载荷(包含Foo有效载荷的专用原型)

并在我的grpc服务定义中使用“请求”,如下所示:

/NOENTRY

为此,最好只定义一次service SessionManager { rpc CreateSession (CreateSessionRequest) returns (CreateSessionResponse) {} rpc DropSession (DropSessionRequest) returns (DropSessionResponse) {} } 原型并将其重新用于我要创建的所有请求。

Request

代替这样做:

message Request {
    string messageId = 1;
    string origin = 2;
    string correlationId = 3;
    int32 sentAt = 4;
    string type = 5;
    int32 version = 6;
    google.protobuf.Any metadata = 7;
    google.protobuf.Any payload = 8;
}

这有可能吗?

1 个答案:

答案 0 :(得分:0)

尽管还有其他方法可以做到,但这绝对是可能的。您可以将公共字段分解为一条消息,该消息包含在您的每个请求/响应中:

message CommonRequestFields {
  string messageId = 1;
  string origin = 2;
  string correlationId = 3;
  int32 sentAt = 4;
  string type = 5;
  int32 version = 6;
}

您可以将其作为每种请求消息类型的正式字段包括在内,而无需依赖Any

message CreateSessionRequest {
  CommonRequestFields common = 1;
  Session session = 2;
  // ...
}

message DropSessionRequest {
  CommonRequestFields common = 1;
  string sessionId = 2;
  // ...
}

这种方法有几个好处:

  • 为每个请求添加通用字段很容易
  • 您可以在客户端和服务器上以相同的方式处理每个请求公用字段
  • 字段ID和名称不会干扰特定于请求的字段ID和名称

但是,有一些缺点:

  • 您需要检查公共字段是否存在,而不是直接访问该字段
  • 某些请求可能不需要所有通用字段,从而导致消息膨胀
  • 随着需求的变化,今天常见的情况可能会在6个月内不再常见。

最后,如果您使用的是gRPC,则可以将元数据与每个请求一起发送,该请求位于请求主体之外。元数据字段是字符串键值对(与HTTP标头相同),如果要为每个请求或响应发送它们,则它们可能是合适的。您甚至可以将原型编码为标头字段,尽管这可能需要使用一些更高级的API。