message Foo {
bytes file1 = 1; // chunkable
bytes file2 = 2; // chunkable
repeated bytes listOfFiles = 3; // chunkable
int64 someField = 4;
}
and add a union-like serialized bytes tag that is empty save for gRPC use:
message Foo {
bytes file1 = 1; // chunkable
bytes file2 = 2; // chunkable
repeated bytes listOfFiles = 3; // chunkable
int64 someField = 4;
bytes serialized = 9999;
}
So we'd do something like:
# server side
f = someMessageFoo(file1=someData, file2=someData2);
g = Foo() # emptyFoo
g.serialized = f.SerializeToString() # all the other fields of g is empty.
server.Send(g) # use the streaming API calls with a chunk size of 4MB
Then on the client side we'd deserialize this similarly via original_f = ParseFromString(new_g.serialized) to get back our message.
Granted we'd need to stuff everything into ram along the way, but it's not a big issue for us. Granted there's a fair bit of boilerplate to do this (and that we'd need to add the rather unfortunate serialized field to all our messages).
Is there a better way?