Hi,

By working closely with Tinkerpop I have been interacting quite a bit with
the GraphSON format and I have come up with the need of using the
"embedTypes" option of the GraphSON Mapper to get more insight of the types
of the data I was transferring through the GraphSON payload.

By default vertices, edges, having properties that have another type than
the natively supported types in the JSON format are encoded as their String
representation. Meaning that a Vertex property being a UUID will look like
"24B7DED2-F72A-11E5-815D-79DF61FECC63" which, for the user consuming the
JSON produced by the GraphSONWriter, will not be distinguishable from being
a String or a UUID. That is usually why you need to activate the type
embedding of GraphSON. Documentation about the current output of GraphSON
typing :
http://tinkerpop.apache.org/docs/3.1.1-incubating/reference/#graphson-reader-writer

However, right now, embedding types with GraphSON comes with a few trade
offs :

   - It is very verbose, mostly because Arrays and Maps types are embedded.
   But Arrays and Maps are natively supported in JSON, and other native types
   like Strings or booleans do not appear typed, so these types should
   logically also be excluded, since natively supported in JSON.
   - It is not consistent, if the type is to be embedded in a JSON Object,
   it will come as a JSON Object's element, a key-value pair {"@class" :
   "java.util.HashMap", ... }, whereas if the type is to be embedded in a JSON
   Array, it will be embedded in "best-effort" and put as a simple value that
   will be ["java.util.HashMap", ... ], hence it makes it difficult to
   automatically parse typed results.
   - It is Java centric.

I'd like to propose a format to encapsulate values format, that would
address the points mentioned above, in which the main idea being that
whenever a type needs to be embedded, the value itself and the type would
be encapsulated in an Array, and the first element is a JSON Object
containing only the key/value pair {"@class": "TypeName"}, the second
element being the value.

A Short integer value encoded would change from :

2

*untyped, to :

[{"@class":"Short"}, 2]

with the type.

It's just an example, but I thought this format would be robust enough. And
properties or other elements for which types are natively supported in JSON
would not need the additional metadata about their types, like it is now
with GraphSON. I have a working prototype for this.

Taking the Tinkerpop's doc example of GraphSON embedded types and applying
the proposed changes :

-----------------------------

{
   "@class":"java.util.HashMap",
   "id":1,
   "label":"person",
   "outE":{
      "@class":"java.util.HashMap",
      "created":[
         "java.util.ArrayList",
         [
            {
               "@class":"java.util.HashMap",
               "id":9,
               "inV":3,
               "properties":{
                  "@class":"java.util.HashMap",
                  "weight":0.4
               }
            }
         ]
      ],
      "knows":[
         "java.util.ArrayList",
         [
            {
               "@class":"java.util.HashMap",
               "id":7,
               "inV":2,
               "properties":{
                  "@class":"java.util.HashMap",
                  "weight":0.5
               }
            },
            {
               "@class":"java.util.HashMap",
               "id":8,
               "inV":4,
               "properties":{
                  "@class":"java.util.HashMap",
                  "weight":1
               }
            }
         ]
      ]
   },
   "properties":{
      "@class":"java.util.HashMap",
      "name":[
         "java.util.ArrayList",
         [
            {
               "@class":"java.util.HashMap",
               "id":[
                  "java.lang.Long",
                  0
               ],
               "value":"marko"
            }
         ]
      ],
      "age":[
         "java.util.ArrayList",
         [
            {
               "@class":"java.util.HashMap",
               "id":[
                  "java.lang.Long",
                  1
               ],
               "value":29
            }
         ]
      ]
   }
}


--------------------------------------------------------------

With the changes :

{
   "id":1,
   "label":"person",
   "outE":{
      "created":[
         {
            "id":9,
            "inV":3,
            "properties":{
               "weight":0.4
            }
         }
      ],
      "knows":[
         {
            "id":7,
            "inV":2,
            "properties":{
               "weight":0.5
            }
         },
         {
            "id":8,
            "inV":4,
            "properties":{
               "weight":1
            }
         }
      ]
   },
   "properties":{
      "name":[
         {
            "id":[
               {"@class":"Long"},
               0
            ],
            "value":"marko"
         }
      ],
      "age":[
         {
            "id":[
               {"@class":"Long"},
               1
            ],
            "value":29
         }
      ]
   }
}

----------------------------------------------------

Open to suggestions and your feedback.



Cheers!

--
Kévin Gallardo.
kgdo.me

Reply via email to