0

I am a jolt newbie. I have the following question, I have a JSON document structure of which may vary based on the type property. See my example below. { "recipientId": "xxx", "messages": [ { "type": "text", "text": "hi there!" }, { "type": "image", "url": "http://example.com/image.jpg", "preview": "http://example.com/thumbnail.jpg" } ] } After transformation I would like to receive the following output: { "messages" : [ { "text" : "hi there!", "type" : "text" }, { "type" : "image", "url" : "http://example.com/image.jpg", "preview": "http://example.com/thumbnail.jpg" } ], "to" : "xxx" }

Here is the spec that I came up with: [ { "operation": "shift", "spec": { "recipientId": "to", "messages": { "*": { "type": "messages[&1].type", "text": "messages[&1].text", "url": "messages[&1].url", "preview": "messages[&1].previewImageUrl" } } } } ]

The problem with this approach is that if I have "type": "text" and if I also throw "preview" property with the value, it will not make sense as the type text should not have "preview" property set. So, I would like jolt to either ignore some properties based on the value of "type" property or avoid transforming such payloads.

Is there a way to do such "validations" in JOLT? The other option that I see would be validating it with Jackson type hierarchy.

Ihor M.
  • 2,728
  • 3
  • 44
  • 70

1 Answers1

0

What you can do is match down to the value of "type", and then jump back up the tree some, and process the message as a "text" type or an "image" type.

Input

{
  "recipientId": "xxx",
  "messages": [
    {
      "type": "text",
      "text": "hi there!",
      "preview": "SHOULD NOT PASS THRU"
    },
    {
      "type": "image",
      "url": "http://example.com/image.jpg",
      "preview": "http://example.com/thumbnail.jpg"
    }
  ]
}

Spec

[
  {
    "operation": "shift",
    "spec": {
      "recipientId": "to",
      "messages": {
        "*": { // the array index of the messages array, referenced below 
               // as [&2] or [&4] depending how far down they have gone 
          "type": {
            // always pass the value of type thru
            "@": "messages[&2].type",

            "text": {
              // if the value of type was "text", then
              //  go back up the tree 3 levels (0,1,2)
              //  and process the whole message as a "text" type
              "@2": {
                "text": "messages[&4].text"
              }
            },
            "image": {
              "@2": {
                // if the value of type was "image", then
                //  go back up the tree 3 levels (0,1,2)
                //  and process the whole message as a "image" type
                "url": "messages[&4].url",
                "preview": "messages[&4].previewImageUrl"
              }
            }
          }
        }
      }
    }
  }
]
Milo S
  • 4,466
  • 1
  • 19
  • 22
  • Thanks a lot for your reply, much appreciated! I have tried your spec. It does allow to skip properties that do not belong with the specific message type. But it doesn't validate if all properties that are vital for specific message type are present. For instance, if "type" is set to "text" I would expect jolt to fail transformation if "text" property is not present in the message. In reality, jolt performs transformation even without important keys. – Ihor M. Aug 11 '17 at 17:14
  • Is there a way to force jolt to fail transformation if a mandatory key is not in the tree? – Ihor M. Aug 11 '17 at 17:15
  • No, jolt is specifically designed not to fail. For things like that (this or that key is mandatory) should use a different tool like some kind of Json Schema. – Milo S Aug 23 '17 at 16:00
  • Thanks for your clarification. – Ihor M. Aug 23 '17 at 18:51