proto文件设置ResponseMessage 为了返回数据的一致性,要求有3个字段:code, message, data. 其中code为数值型,message为string类型,data为任意类型 2 months ago
博客大纲
定义通用的 ResponseMessage
以下是一个符合你要求的 Protocol Buffers 响应消息定义,包含 code
、message
和 data
三个字段,其中 data
为任意类型:
方案1:使用 google.protobuf.Any
(推荐)
syntax = "proto3";
import "google/protobuf/any.proto";
message ResponseMessage {
int32 code = 1; // 状态码
string message = 2; // 状态信息
google.protobuf.Any data = 3; // 响应数据,可以是任意类型
}
方案2:使用 oneof
(适用于已知有限类型)
syntax = "proto3";
message ResponseMessage {
int32 code = 1;
string message = 2;
oneof data {
string string_data = 3;
int32 int_data = 4;
bool bool_data = 5;
bytes binary_data = 6;
// 可以添加更多已知类型
}
}
方案3:使用 google.protobuf.Value
(类似JSON的灵活性)
syntax = "proto3";
import "google/protobuf/struct.proto";
message ResponseMessage {
int32 code = 1;
string message = 2;
google.protobuf.Value data = 3; // 可以是null, number, string, bool, list或object
}
推荐实现
推荐使用方案1(Any 类型),因为它:
- 可以包装任何 protobuf 消息类型
- 是官方标准解决方案
- 各语言都有良好的支持库
使用示例(Go语言)
import (
"google.golang.org/protobuf/types/known/anypb"
)
// 创建响应
func CreateSuccessResponse(data proto.Message) (*ResponseMessage, error) {
anyData, err := anypb.New(data)
if err != nil {
return nil, err
}
return &ResponseMessage{
Code: 200,
Message: "Success",
Data: anyData,
}, nil
}
// 使用示例
user := &User{Name: "John", Age: 30}
resp, err := CreateSuccessResponse(user)
客户端解析示例
// 解析响应
func ParseResponse(resp *ResponseMessage, target proto.Message) error {
if resp.GetData() != nil {
return resp.GetData().UnmarshalTo(target)
}
return errors.New("no data in response")
}
// 使用示例
var user User
if err := ParseResponse(response, &user); err != nil {
// 处理错误
}
这种设计模式类似于 REST API 中常见的响应结构,提供了良好的前后端交互一致性。