Search code examples
protocol-buffersgrpc

gRPC: defining an rpc which returns one stream and one data


Let's say I have a file I want to transfer using grpc and streaming,

service FileService {
    rpc GetFile(FileRequest) returns (stream FileResponse) {}
}

message FileRequest {
    int32 id = 1;
}

message FileResponse {
    bytes chunk = 1;
}

So I want client to know how many chuncks will be sent in total. This data only will be sent for once. I don't want to create a new method, but it seems like I can't add a second return value which will not be a stream. What is my options?


Solution

  • Normally stream doesn't have defined length, if stream has expected length maybe it should be an array?

    But trying to solve it using steam you can maybe try use oneof and first record of the stream will contain length and rest actual data

    message FileResponse {
        oneof data {
            int32 length = 1;
            bytes chunk = 2;
        };
    }
    

    The issue here is that length can be sent also in the middle of the stream

    Another way to somehow handle it is to use optional, then generated code should also provide another property called HasLength(at least C# has it like that), maybe instead of length in this case you can name it remaining and update it

    message FileResponse {
        optional int32 length = 1;
        bytes chunk = 2;
    }
    

    I hope it helps