title: Is "google/protobuf/struct.proto" the best way to send dynamic JSON over GRPC?
body: <p>I have a written a simple GRPC server and a client to call the server (both in Go). Please tell me if using golang/protobuf/struct is the best way to send a dynamic JSON with GRPC.
  In the example below, earlier I was creating <code>Details</code> as a <code>map[string]interface{}</code> and serializing it. Then I was sending it in protoMessage as <code>bytes</code> and was de-serializing the message on the server side.</p>
  <p>Is it the best/efficient way to do it or should I define Details as a struct in my proto file?</p>
  <p>Below is User.proto file</p>
  <pre><code>syntax = &quot;proto3&quot;;
  package messages;
  import &quot;google/protobuf/struct.proto&quot;;
  
  service UserService {
      rpc SendJson (SendJsonRequest) returns (SendJsonResponse) {}
  }
  
  message SendJsonRequest {
      string UserID = 1;
      google.protobuf.Struct Details = 2;
  }
  
  message SendJsonResponse {
      string Response = 1;
  }
  </code></pre>
  <p>Below is client.go file</p>
  <pre><code>package main
  import (
      &quot;context&quot;
      &quot;flag&quot;
      pb &quot;grpc-test/messages/pb&quot;
      &quot;log&quot;
      &quot;google.golang.org/grpc&quot;
  )
  
  func main() {
      var serverAddr = flag.String(&quot;server_addr&quot;, &quot;localhost:5001&quot;, &quot;The server address in the format of host:port&quot;)
      opts := []grpc.DialOption{grpc.WithInsecure()}
      conn, err := grpc.Dial(*serverAddr, opts...)
      if err != nil {
          log.Fatalf(&quot;did not connect: %s&quot;, err)
      }
      defer conn.Close()
  
      userClient := pb.NewUserServiceClient(conn)
      ctx := context.Background()
  
      sendJson(userClient, ctx)
  }
  
  func sendJson(userClient pb.UserServiceClient, ctx context.Context) {
      var item = &amp;structpb.Struct{
          Fields: map[string]*structpb.Value{
              &quot;name&quot;: &amp;structpb.Value{
                  Kind: &amp;structpb.Value_StringValue{
                      StringValue: &quot;Anuj&quot;,
                  },
              },
              &quot;age&quot;: &amp;structpb.Value{
                  Kind: &amp;structpb.Value_StringValue{
                      StringValue: &quot;Anuj&quot;,
                  },
              },
          },
      }
  
      userGetRequest := &amp;pb.SendJsonRequest{
          UserID: &quot;A123&quot;,
          Details: item,
      }
  
      res, err := userClient.SendJson(ctx, userGetRequest)
  }
  </code></pre>