如何组织.proto文件以便在可能的情况下重用消息?

huangapple go评论83阅读模式
英文:

How to organize proto file to re-use message if possible?

问题

我最近开始在我的golang项目中使用protobuf。我创建了下面这个简单的protobuf文件。我有三个不同的端点。

  • GetLinkCustomerRequest作为输入参数,返回CustomerResponse
  • GetBulkLinksBulkCustomerRequest作为输入参数,返回BulkCustomerResponse
  • StreaLinksStreamRequest作为输入参数,返回CustomerResponse

我想知道是否有办法改进下面的proto文件,因为CustomerRequestBulkCustomerRequest除了resources字段外,大部分内容都是相同的,所以存在重复。同样,StreamRequest输入参数也是一样的,只接受clientId作为输入参数。在协议缓冲区中是否有可以重用另一个消息类型的内容的方法?

是否有更好或更高效的方法来组织下面的proto文件,以便根据需要重用消息?

syntax = "proto3";

option go_package = "github.com/david/customerclient/gen/go/data/v1";

package data.v1;

service CustomerService {
  rpc GetLink(CustomerRequest) returns (CustomerResponse) {};
  rpc GetBulkLinks(BulkCustomerRequest) returns (BulkCustomerResponse) {};
  rpc StreaLinks(StreamRequest) returns (CustomerResponse) {};
}

message CustomerRequest {
  int32 clientId = 1;
  string resources = 2;
  bool isProcess = 3;
}

message BulkCustomerRequest {
  int32 clientId = 1;
  repeated string resources = 2;
  bool isProcess = 3;
}

message StreamRequest {
  int32 clientId = 1;
}

message CustomerResponse {
  string value = 1;
  string info = 2;
  string baseInfo = 3;
  string link = 4;
}

message BulkCustomerResponse {
  map<string, CustomerResponse> customerResponse = 1;
}
英文:

I recently started working with protobuf in my golang project. I created below simple protobuf file. I have three different endpoints.

  • GetLink takes CustomerRequest as an input parameter and returns back CustomerResponse
  • GetBulkLinks takes BulkCustomerRequest as an input parameter and returns back BulkCustomerResponse
  • StreaLinks takes StreamRequest as an input parameter and returns back CustomerResponse

I am wondering if there is any way we can improve below proto file because CustomerRequest and BulkCustomerRequest has mostly everything in common except resources field so there is a duplication. And same goes with StreamRequest input parameter as it only takes clientId as the input parameter. Is there anything in protocol buffer which can reuse stuff from another message type?

Is there any better or efficient way to organize below proto file which reuses message accordingly?

syntax = &quot;proto3&quot;;
option go_package = &quot;github.com/david/customerclient/gen/go/data/v1&quot;;
package data.v1;
service CustomerService {
rpc GetLink(CustomerRequest) returns (CustomerResponse) {};
rpc GetBulkLinks(BulkCustomerRequest) returns (BulkCustomerResponse) {};
rpc StreaLinks(StreamRequest) returns (CustomerResponse) {};
}
message CustomerRequest {
int32 clientId = 1;
string resources = 2;
bool isProcess = 3;
}
message BulkCustomerRequest {
int32 clientId = 1;
repeated string resources = 2;
bool isProcess = 3;
}
message StreamRequest {
int32 clientId = 1;
}
message CustomerResponse {
string value = 1;
string info = 2;
string baseInfo = 3;
string link = 4;
}
message BulkCustomerResponse {
map&lt;string, CustomerResponse&gt; customerResponse = 1;
}

答案1

得分: 3

协议缓冲区(Protocol Buffer)中是否有任何可以重用另一个消息类型中的内容的功能?

组合

但请记住,请求和响应的有效载荷可能会随时间而变化。即使它们今天看起来有一些共同之处,它们明天可能会分歧。毕竟,它们用于不同的RPC。过度耦合会产生相反的效果,并成为技术债务。

由于您的模式每个消息只有不超过三个字段,我建议保持现状。但是,如果您确实需要,可以考虑以下方法:

  • GetLinkGetBulkLinks的共同字段提取到一个单独的消息中,并与之组合:
message CustomerRequestParams {
  int32 clientId = 1;
  bool isProcess = 2;
}

message CustomerRequest {
  CustomerRequestParams params = 1;
  string resources = 2;
}

message BulkCustomerRequest {
  CustomerRequestParams params = 1;
  repeated string resources = 2;
}
  • StreamRequest中重复的clientId看起来很好。可以认为流与一元RPC在概念上是不同的,因此保持它们分开。而且它只有一个字段。
英文:

> Is there anything in protocol buffer which can reuse stuff from another message type?

Composition.

However keep in mind that request and response payloads may change over time. Even if it looks like they have something in common today, they may diverge tomorrow. After all they are used in different RPCs. Then excessive coupling achieves the opposite effect and becomes technical debt.

Since your schema has literally no more than three fields for each message, I would leave everything as is. Anyway, if you really must, you may consider the following:

  • Extract the GetLink and GetBulkLinks common fields in a separate message and compose with that:
message CustomerRequestParams {
int32 clientId = 1;
bool isProcess = 2;
}
message CustomerRequest {
CustomerRequestParams params = 1;
string resources = 2;
}
message BulkCustomerRequest {
CustomerRequestParams params = 1;
repeated string resources = 2;
}
  • StreamRequest looks just fine with repeating clientId. Arguably a stream is conceptually different from a unary RPC, so just keep them separated. And it's just one field.

huangapple
  • 本文由 发表于 2022年2月17日 14:29:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/71153419.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定