Mapping: JSON

Language: MAP:JSON

The JSON mapping language is a simple way to map one simple JSON object to another, with minimal processing.

Comments are allowed in the template.

There are a few primitive constructs:

  • Constants are allowed
  • $ ($a.b[0].c) Reference a variable from the source object
  • ! (!a.b[0].c) Assert that the variable in the source object is present, and reference it, otherwise reject the payload
  • test {{a.b[0].c}} Inject a variable into an interpolated string via handlebars-like syntax
  • {$ref: '$a.b.c', ..operators} A more advanced syntax that references part of the payload and allows operating on it

Simple Mapping

The simplest example is a combination of constants and referencing data in the source payload.

For example, if you had an incoming payload like this:

{
  "a" : 11,
  "b" : {
    "c" : 12
  },
  "name" : "joe"
}

You could write a translator like so:

{
  "my_constant" : "abc",
  "payload_name" : "$name",
  "first_number" : "$b.c",
  "numbers" : "{{a}} and {{b.c}}",
}

which will transform the payload into this:

{
  "my_constant" : "abc",
  "payload_name" : "joe",
  "first_number" : 12,
  "numbers" : "11 and 12"
}

Operators

Operators allow you to transform data in a way that is more than 1:1 mapping.

Available Operators

  • $match: regex Will extract a regex match from a referenced string
  • $assert: regex Will assert that a given referenced string matches a regex, or reject the payload
  • $format: formatStr Will format the referenced data into a string. The referenced value is in the '.' param, eg: my value is {{.}}
  • $join: separator Will join a referenced-list by a separator into a string
  • $pick: picker Will pick an named object out of an array. Similar to _.map
  • $each: {} Will execute an operator on each item of the reference list
  • $substr: {start, length} Will take substring of the reference
  • $split: separator Will split a string by the separator into an array
  • $ifeq: value If the reference value equals the value of the statement, return the evaluated value of the param $then, else $else

Examples

Operators, part of the $ref syntax, allow simple operations on the payload. For example, if you have a payload like:

{
  "csv_values" : "a,b,c,def"
}

and you want to split the comma-separated-values, you could use the $ref syntax with the $split command, like so:

{
  "values" : {
    "$ref" : "$csv_values",
    "$split" : ','
  }
}

You will get an output like this:

{
  "values" : ["a", "b", "c", "def"]
}

In a more complex example, you can nest these. Let's say you want to split the same CSV values, and rejoin them using +

{
  "values" : {
    "$ref" : {
      "$ref" : "$csv_values",
      "$split" : ','
    },
    "$join" : "+"
  }
}

you would get a similar output:

{
  "values" : "a+b+c+def"
}

Complex Example

Here is a more complex example (taken from our unit tests) that shows how a larger json translator might look:

{
  "const": "joe",
  "val": "$a.b",
  "nullval": "$a.dne",
  "deep": {
    "val": "$a.b"
  },
  "assert": "!a.c",
  "str": "hi {{a.b}} from {{a.c}}",
  "explicitRef": {
    "$ref": {
      "$ref": "$long",
      "$match": "\\*([\\w\\s]+)\\*"
    },
    "$format": "hi there, {{.}} and {{a.b}}"
  },
  "arrayRef": {
    "$ref": {
      "$ref": {
        "$ref": "$arr",
        "$pick": "val"
      },
      "$each": {
        "$format": "hi {{.}}"
      }
    },
    "$join": ", ",
    "$substr": {
      "start": 1
    },
    "$assert": "hi \\d+"
  },
  "iftest": {
    "$ref": "$a.b",
    "$ifeq": "mark",
    "$then": 1
  },
  "splittest": {
    "$ref": "$long",
    "$split": " "
  }
}