GRPC Protobuff 3个嵌套消息定义



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

fororequest

  • messageid
  • 相关性
  • Morefields
  • 有效载荷(包含FOO有效载荷的专用原始原始)

并使用我的GRPC服务召唤中的请求:

service SessionManager {
    rpc CreateSession (CreateSessionRequest) returns (CreateSessionResponse) {}
    rpc DropSession (DropSessionRequest) returns (DropSessionResponse) {}
}

为此,只能定义Request 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;
}

您可以将其作为每个请求消息类型上的正式字段,而无需依赖Any

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

这种方法有几个优势:

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

但是,有一些缺点:

  • 您需要检查常见字段,而不是直接访问字段
  • 某些请求可能不需要所有常见字段,导致消息膨胀
  • 随着需求的变化,今天常见的情况可能并不常见。

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

最新更新