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
}
}
}
}
}
Using
Valuehas 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 whatValueis) in which case they can do so directly without any additional string parsing. (And without worrying about non-standard JSON.)