当前位置: 首页 > 工具软件 > Kratos > 使用案例 >

Kratos框架Http请求实现动态json解析

彭胡媚
2023-12-01

问题

有如下callback请求,data会根据type动态变化:

  • pingpong
{
  "type": "PingPong",
  "data": {}
}
  • NewMessage
{
    "type": "NewMessage",
    "data": {
        "id": "{{$guid}}",
        "rootId": "2",
        "content": "hello sd bot",
        "channel": {
            "channelId": "24"
        },
        "mentionsMap": [
            {
                "type": "user",
                "id": "9527"
            }
        ],
        "sender": {
            "profile": {
                "uid": "9527"
            }
        }
    }
}

对应到 kratos项目api文件中的proto定义时,data应该是什么类型呢?

message BotMessageReq{
  string type = 1;     // 消息类型, PingPong,NewMessage,UserJoin
  x data = 2;          // 消息内容, json格式,当type=NewMessage时,为
}

x 一开始我把 data 设置为了 string 类型,但是运行后 json.Unmarshal 会报错,尝试了插件 google/protobuf/any.proto 中的 Any类型也不行。

解决方案

最后,在stackoverflow中搜到的办法:https://stackoverflow.com/questions/52966444/is-google-protobuf-struct-proto-the-best-way-to-send-dynamic-json-over-grpc

使用 google.protobuf.Struct 类型即可:

message BotMessageReq{
  string type = 1;                  // 消息类型, PingPong,NewMessage,UserJoin
  google.protobuf.Struct data = 2;  // 消息内容, json格式,当type=NewMessage时,为 
}

在代码中,这样使用:

if req.Type == pb.BotMessageReq_NewMessage.String(){
   dataStr, err := req.Data.MarshalJSON()
   if err != nil {
      return err
   }

   msg := pb.BotMessage{}
   err = json.Unmarshal(dataStr, &msg)
   if err != nil {
      return err
   }

   // ...
}

参考:https://stackoverflow.com/questions/52966444/is-google-protobuf-struct-proto-the-best-way-to-send-dynamic-json-over-grpc

 类似资料: