2

Questions about attaching a piece of metadata (an "initial" request) when initiating a client-side streaming gRPC have already been asked before (here, here), but some answers are suggesting that it's not possible and suggest using oneof where first request towards a server contains the metadata in question, and subsequent requests contain the actual data to be processed by the server. I'm wondering if it's safe to encode metadata with a binary encoding of choice and send it to the server where it can be extracted from the Context object and deserialized back into meaningful data. I'm fairly certain that it's perfectly fine when it comes to text-based encodings such as JSON. But what about protobuf? Assuming we define our service like so:

service MyService {
  rpc ChitChat (stream ChatMessage) returns (stream ChatMessage);
}

message ChatMessage {
  // ...
}

message Meta {
  // ...
}

We can include a Meta object in the request:

meta := &pb.Meta{
    // ...
}
metab, err := proto.Marshal(meta)
if err != nil {
    log.Fatalf("marshaling error: %v", err)
}
newCtx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs("meta-bin", string(metab)))
// ...ChitChat(newCtx)

And access it on the server side:

func (s *server) ChitChat(stream pb.MyService_ChitChatServer) error {
    md, ok := metadata.FromIncomingContext(stream.Context())
    if !ok {
        return fmt.Errorf("no metadata received")
    }
    metaStr := md.Get("meta-bin")
    if len(metaStr) != 1 {
        return fmt.Errorf("expected 1 md; got: %v", len(metaStr))
    }
    meta := new(pb.Meta)
    if err := proto.Unmarshal([]byte(metaStr[0]), meta); err != nil {
        return fmt.Errorf("error during deserialization: %v", err)
    }

    // ...
    return nil
}

It appears to be working quite well - am I missing something? How easy is it to shoot yourself in the foot with this approach?

shooqie
  • 950
  • 7
  • 17

1 Answers1

1

Yes, gRPC supports binary headers, so this approach isn't invalid; it is a little less clear that it is expected, but then: that's true for the oneof approach too, so ... not much difference there.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900