Search code examples
protocol-buffersgrpcprotobuf.js

protobuf map value is object or array of object


I have

message {
   message leadsEntity{
     optional string name = 1;
   }
   optional string description = 1;
   map <string, leadsEntity>  entity = 2;
}

Now I can have 2 types of responses-

    // 1st case
    {
       description : "this is test",
       entity : {
         key1 : { name : "name1" },
         key2 : { name : "name2" }
       }
    }

Or

   // 2nd case
   {
       description : "this is test",
       entity : {
         key1 : { name : "name1" },
         key2 : [ { name : "name2" } ] //the value in array now
       }
    }

Now the above given proto message works perfectly for 1st case. But how to handle 2nd case? where the value is an object array?


Solution

  • I assume by the use of optional that you prefer proto2

    Your existing proto is invalid.

    Your response types are going to make your life difficult because the entity values are a union of types.

    Perhaps something like this:

    syntax = "proto2";
    
    message X {
       message LeadsEntity{
          optional string name = 1;
       }
       message LeadsEntities {
          repeated LeadsEntity leads_entity = 1;
       }
       message Value {
          oneof These {
             LeadsEntity leads_entity = 1;
             LeadsEntities leads_entities = 2;
          }
       }
       optional string description = 1;
       map <string, Value>  entity = 2;
    }
    
    • I gave the root message the name X
    • I added LeadsEntities to hold the repeated LeadsEntity
    • I added Value to hold the oneof
    from google.protobuf.json_format import MessageToJson
    
    import x_pb2
    
    x = x_pb2.X()
    x.description = "this is a test"
    x.entity["key1"].leads_entity.name = "name1"
    
    le = x.entity["key2"].leads_entities.leads_entity.add()
    le.name = "name2"
    
    print(MessageToJson(x))
    
    

    Yields:

    {
      "description": "this is a test",
      "entity": {
        "key1": {
          "leadsEntity": {
            "name": "name1"
          }
        },
        "key2": {
          "leadsEntities": {
            "leadsEntity": [
              {
                "name": "name2"
              }
            ]
          }
        }
      }
    }