我想以这样的嵌套方式定义我的消息:
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使用。