Skip to content
Advertisement

Protobuf repeated fields to json array mapping

I’m using Java, Spring-boot, Hibernate stack and protocol buffers as DTO for communication among micro-services. At reverse proxy, I convert the protobuf object to json using protobuf’s java support.

I have the following structure

message Item {
    int64 id = 1;
    string name = 2;
    int64 price = 3;
}

message MultipleItems {
    repeated Item items = 1;
}

Converting the MultipleItems DTO to json gives me the following result:

{
    "items": [
        {
            "id": 1,
            "name": "ABC",
            "price": 10
        },
        {
            "id": 2,
            "name": "XYZ",
            "price": 20
        }
    ]
}

In the generated json, I’ve got the key items that maps to the json array.

I want to remove the key and return only json array as the result. Is there a clean way to achieve this?

Advertisement

Answer

I think it’s not possible.

repeated must appear as a modifier on a field and fields must be named.

https://developers.google.com/protocol-buffers/docs/proto3#json

There’s no obvious reason why Protobuf could not support this1 but, it would require that its grammar be extended to support use of repeated at the message level rather than its current use at the field level. This, of course, makes everything downstream of the proto messages more complex too

JSON, of course, does permit it.

It’s possible that it complicates en/decoding too (an on-the-wire message could be either a message or an array of messages.

1 Perhaps the concern is that generated code (!) then must necessarily be more complex too? Methods would all need to check whether the message is an array type or a struct type, e.g.:

func (x *X) SomeMethod(ctx context.Context, []*pb.SomeMethodRequest) ...

And, in Golang pre-generics, it’s not possible to overload methods this way and they would need to have distinct names:

func (x *X) SomeMethodArray(ctx context.Context, []*pb.SomeMethodRequest) ...
func (x *X) SomeMethodMessage(ctx context.Context, *pb.SomeMethodRequest) ...
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement