如何使用json作为protobuf或grpc中的结构成员?

时间:2018-06-26 02:44:47

标签: json protocol-buffers grpc

使用JavaScript开发时,我们始终需要使用rpc传输json。现在我想使用json作为grpc中消息的结构成员。请看下面:

message HelloRequest{
    int32 hello = 1;
    json world = 2
} 

该怎么做?

3 个答案:

答案 0 :(得分:1)

有两种方法可以执行此操作,具体取决于您是否事先了解JSON的结构。如果这样做,您可以简单地为JSON对象编写一条单独的消息,并将其包含在原始消息中:

message SomeJSONMessage {
    // Attributes of your JSON here
}

message HelloRequest {
    int32 hello 1;
    SomeJSONMessage message = 2;
}

之所以可行,是因为每种JSON类型maps natively都属于Protobuf类型。

如果您事先不了解JSON的结构,则必须使用google.protobuf.Struct,它基本上是没有定义结构的JSON:

message HelloRequest {
    int32 hello 1;
    google.protobuf.Struct message = 2;
}

这可以很容易地映射到许多编程语言(JS中的对象,Python中的dict)中的知名类型,但是您不能保证它包含什么属性。

答案 1 :(得分:0)

感谢社区的支持,在这里我会使用 google.protobuf.Structgogo/protobuf/types/struct.pb .go

import "google/protobuf/struct.proto";

message HelloRequest{
    int32 hello = 1;
    google.protobuf.Struct world = 2
}

我目前正在使用 go v1.16grpc-gateway v1.16。如果您更喜欢 gogo protobuf 而不是 google protobuf(< strong>xx.pb.go 位于 pb 文件夹中的文件):

    --gogo_out=plugins=grpc,\
Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types,\
Mgoogle/protobuf/duration.proto=github.com/gogo/protobuf/types,\
Mgoogle/protobuf/empty.proto=github.com/gogo/protobuf/types,\
Mgoogle/protobuf/struct.proto=github.com/gogo/protobuf/types,\
Mgoogle/api/annotations.proto=github.com/gogo/googleapis/google/api,\
Mgoogle/protobuf/field_mask.proto=github.com/gogo/protobuf/types:\
pb \

最后但并非最不重要的一点是,我可以提供一个使用 gogo protobuf 的示例。请看下面的代码!

import (
     "github.com/gogo/protobuf/jsonpb"
     "github.com/gogo/protobuf/types"
)

.....
world := &types.Struct{}
helloRequest := &pb.HelloRequest{World: world}
bts := []byte(`{"status":200,"user":{"id":1,"name":"A","age":26,"phone":null,"skills":{"backend":"Golang","frontend":"React"},"hobbies":["coding","running"]}}`)
    
// Every pb are proto.Message so that we have to use jsonpb package 
// instead of json package
err := jsonpb.Unmarshal(bytes.NewBuffer(bts), world)
if err != nil {
    panic(err)
}

响应 json 应该是:

{ 
  "hello": 0,
  "world": {
    "status": 200,
    "user": {
      "id": 1,
      "name": "A",
      "age": 26,
      "phone": null,
      "skills": {
        "backend": "Golang",
        "frontend": "React"
      },
      "hobbies": [
        "coding",
        "running"
      ]
    }
  }
}

答案 2 :(得分:0)

如果您非常想要该 JSON 结构并且不关心您的 proto 文件有多漂亮,您可以使用 google.protobuf.Struct 类型来构建自定义 JSON 结构。

https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/struct.proto

在这种情况下,您可能需要 google.protobuf.ListValue