Search code examples
web-servicesprotocol-buffersgrpcprotobuf-c

How data is sent from client to (multi-service) server in gRPC


I am using the gRPC client server framework in one of my application (speech recognition). There are a few important things I want to clarify with my observations.

1. How the optional data field sent, when it is not populated by the client?

Let's see this below example: (assume proto3 is used so all the fields are optional by default)

service NameStudent {
    rpc GetRoll(Student) returns (Details) {}
}

#Student'd details
message Student{
    int32 roll = 1;
    string name = 2;
    string gender = 4;
    int32 age = 3;
    DOB dateofbirth = 5;
}

#Students Date of Birth
message DOB {
    int32 dd = 1;
    int32 mm = 2;
    int32 yy = 3;
}

#Parent's details
message Parent{
    string parent =1;
}

#Students all details (includes student + parent)
message Details {
    Student student = 1;
    Parent parent = 4;
}

Assume that the service takes (input from client) some of the student details, say roll, name, and age, and return that student's (all) details

so now if instead of sending all 3 details (i.e. roll, name and age), even any one or two details can also be sent and (logically assume that) the service works.

In such cases, will the server receive all fields (with blanks/NULLs for omitted fields) or will the client not send that omitted information at all? (see below representations of binary data sent from client)

// roll and name filled
// age is left blank
// gender and DOB are always sent blank from client
{
    roll: 170012,
    name: "John Doe",
    age: ,
    gender: "",
    dateofbirth: {
           dd: ,
           mm: ,
           yy: 
    }
}

OR

//only roll and name is sent and rest is just not sent
{
    roll: 170012,
    name: "John Doe"
}

2. Possible to connect single stub for two services?

If the server offers 2 services and I am making a client stub, will I be able to connect 2 channels from same stub to the same server accessing 2 different services of it?


Solution

  • Question 1

    Take a look at this protobuf documentation. In particular:

    For any non-repeated fields in proto3, or optional fields in proto2, the encoded message may or may not have a key-value pair with that field number.

    In practice though, I have observed that optional fields with default values are omitted in the serialization. When the protobuf is deserialized, the parser will interpret the missing field as the default value. You can observe this behavior yourself by using the SerializeToString() method on Python protobuf objects.

    Question 2

    It's absolutely possible to attach multiple gRPC services to the same server and to interact with multiple services from the same client-side channel. gRPC uses HTTP2 paths to differentiate between multiple services attached to the same server. Take a look at this gRPC Python generated code for an example of that. add_GreeterServicer_to_server associates a user-defined handler with the path /helloworld.Greeter/SayHello, which the stub then uses to identify that service on the server.