【问题标题】:grpc Protobuff 3 nested message definitionsgrpc Protobuf 3 嵌套消息定义
【发布时间】:2019-07-07 13:31:46
【问题描述】:

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

FooRequest

  • messageId
  • correlationId
  • 更多字段
  • payload(包含 Foo 有效负载的专用 proto)

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

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;
}

不要这样做:

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;
}

这有可能吗?

【问题讨论】:

    标签: protocol-buffers grpc


    【解决方案1】:

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

    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 标头相同),如果您为每个请求或响应发送它们可能是合适的。您甚至可以将 protos 编码为标头字段,但这可能需要一些更高级的 API 使用。

    【讨论】:

    • 作为标题一部分的元数据选项是我想要的。 gRPC 专门为此类场景添加了此功能。如果您的客户端方法使用异步方法,您可以通过 ResponseAsync 访问回调对象
    猜你喜欢
    • 1970-01-01
    • 2022-06-30
    • 1970-01-01
    • 2018-09-15
    • 1970-01-01
    • 2021-06-21
    • 2019-01-06
    • 2019-01-20
    • 2017-08-14
    相关资源
    最近更新 更多