skip to Main Content

Goal
I want to save an object serialized as JSON in a gRPC message.

Info
The Microsoft documentation says to use the type google.protobuf.Value for JSON.
The serialized object should then be converted with Value.Parser.ParseJson.
And converted again on the other side with JsonFormatter.Default.Format so that it can then be deserialized.
https://learn.microsoft.com/en-us/aspnet/core/grpc/protobuf?view=aspnetcore-8.0#value

Problem
It is not explained why.
If I use string as type, I do not have to convert it with Value.Parser.ParseJson.

Question
Is it okay if I use string or does google.protobuf.Value have an advantage that I don’t see?
(You can see differences in the output whether string or google.protobuf.Value is used.)

gRPC Message

message PingResponseMessage {
  google.protobuf.Timestamp ResponseTimeUtc = 1;
  string JsonString = 2;
  google.protobuf.Value JsonValue = 3;
}

Create gRPC Message

Settings settings = new() {Name = "Dog", Port = 4000};
PingResponseMessage pingResponseMessage = new()
{
    ResponseTimeUtc = Timestamp.FromDateTime(DateTime.UtcNow),
    JsonString      = JsonConvert.SerializeObject(settings),
    JsonValue       = Value.Parser.ParseJson(JsonConvert.SerializeObject(settings)),
};

Output

{
    "ResponseTimeUtc": {
        "seconds": "1711525732",
        "nanos": 394125400
    },
    "JsonString": "{"Name":"Dog","Port":4000}",
    "JsonValue": {
        "struct_value": {
            "fields": {
                "Name": {
                    "string_value": "Dog"
                },
                "Port": {
                    "number_value": 4000
                }
            }
        }
    }
}

2

Answers


  1. Is it okay if I use string or does google.protobuf.Value have an advantage that I don’t see?

    Using Value has the advantage that anyone using the structure on the other side doesn’t have to parse the JSON themselves, or worry about oddities that particular JSON formatters have (e.g. representations of infinity etc).

    If the other side actually wants it as JSON (e.g. to deserialize to a different representation using Json.NET or System.Text.Json) then it’s somewhat inefficient to go via Value. On the other hand, the other side might be happy to process it as "the same structure that is normally represented as JSON" (which is basically what Value is) in which case they can do so directly without any additional string parsing. (And without worrying about non-standard JSON.)

    Login or Signup to reply.
  2. This started out as a comment but getting too long, so:
    I’m not sure that the documentation say what you think it says.
    The way I understand it, they simply say that instead of working with the Value methods (i.e. Value.ForStruct, Value.ForBool etc’), if the value is complex, it might be easier to use Value.Parser.ParseJson and give it a json string).

    The example they show is for a relatively simple struct with only a couple of properties – and the code for creating and for reading it is quite long and cumbersome in comparison to the code for creating and reading its json equivalent.

    That being said, I do think Jon Skeet’s answer addressed your question exactly.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search