Protocol buffers grpc Protobuff 3嵌套消息定义

Protocol buffers grpc Protobuff 3嵌套消息定义,protocol-buffers,grpc,Protocol Buffers,Grpc,我希望以如下嵌套方式定义我的消息: service SessionManager { rpc CreateSession (CreateSessionRequest) returns (CreateSessionResponse) {} rpc DropSession (DropSessionRequest) returns (DropSessionResponse) {} } 食物请求 消息ID 相关ID 莫尔菲尔德 有效载荷(包含Foo有效载荷的专用proto) 并在我

我希望以如下嵌套方式定义我的消息:

service SessionManager {
    rpc CreateSession (CreateSessionRequest) returns (CreateSessionResponse) {}
    rpc DropSession (DropSessionRequest) returns (DropSessionResponse) {}
}
食物请求

  • 消息ID
  • 相关ID
  • 莫尔菲尔德
  • 有效载荷(包含Foo有效载荷的专用proto)
并在我的grpc服务定义中使用如下请求:

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

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;
}
而不是这样做:

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

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

这是可能的吗?

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

message CommonRequestFields {
  string messageId = 1;
  string origin = 2;
  string correlationId = 3;
  int32 sentAt = 4;
  string type = 5;
  int32 version = 6;
}
您可以在每个请求消息类型上将其作为正式字段包含,而无需依赖于
任何

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

message DropSessionRequest {
  CommonRequestFields common = 1;
  string sessionId = 2;
  // ...
}
这种方法有几个好处:

  • 为每个请求添加公共字段很容易
  • 您可以在客户端和服务器上以相同的方式处理每个请求公共字段
  • 字段ID和名称不会干扰特定于请求的字段ID和名称
然而,也有一些不利因素:

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

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

作为头的一部分的元数据选项是我想要的。gRPC专门针对此类场景添加了此选项。如果客户端方法使用异步方法,则可以通过ResponseAsync访问回调对象