Search code examples
c#requestgrpcresponse

Is Grpc's request can return different responses for some conditions


service Greeter {
  rpc OpenChannel(RequestOpenChannel) returns (stream ResponseOpenChannel);}

message RequestOpenChannel{
    int32 task_id =1;
}

message ResponseOpenChannel {
     int32 response_id =1;
}

This is my ProtoFile. My TaskID like (1 = ConditionOne, 2 = ConditionTwo).

I want to send response from server to the client after looking some condition.

service Greeter {
  rpc OpenChannel(RequestOpenChannel) returns (stream ResponseOpenChannel , ResponseOpenChannel2);}
message ResponseOpenChannel2 {
     int32 response_id =1;
}

And that is my expected server code.

if(request.TaskID == 1){ ResponseOpenChannel1 response = some stuff }

else if(request.TaskID == 2){ ResponseOpenChannel2 response = some stuff }

Solution

  • This sounds like a job for oneof; if you're using contract-first .proto, then you'd have something like:

    message ResponseOpenChannel {
        int32 response_id =1;
        oneof response {
            Foo foo = 2;
            Bar bar = 3;
        }
    }
    message Foo { ... }
    message Bar { ... }
    

    and you'd return a ResponseOpenChannel with either a foo = new Foo {...} or a bar = new Bar {...}


    If you're using code-first protobuf-net[.Grpc], then this is 100% wire-identical to:

    [ProtoContract]
    [ProtoInclude(2, typeof(Foo))]
    [ProtoInclude(3, typeof(Bar))]
    class ResponseOpenChannel
    {
        [ProtoMember(1)]
        public int ResponseId {get;set;}
    }
    [ProtoContract]
    public class Foo : ResponseOpenChannel
    {...}
    [ProtoContract]
    public class Bar : ResponseOpenChannel
    {...}
    

    and you would return a new Foo {...} or a new Bar {...}.