JsonTransform

Use the JsonTransform policy to adjust the JSON data returned from the target server.

The JSON can be adjusted in these ways:

  • Selected properties can be deleted.
  • Properties can be added with default values.
  • An entirely new JSON response can be created by using selected parts of the original response.
  • Any/All of the above can be applied during the same invocation of the policy.

Note that any/all deletions are done before any/all default values additions and before any/all transformations. In the case of deletions if your JSON paths refer to properties/objects/array-elements that do not exist, the delete request is ignored. In the case of deletions if your JSON paths refer to properties/objects/array-elements that do not exist, the resulting property will have a value of undefined.

Resources

The JSON transform policy relies on a special language called JSONPath that is used to select objects, sub-objects, properties, and array elements with the JSON document.

Examples

For these examples, assume that the target server normally returns the JSON response shown below:

Sample JSON Response from Target Server:

{
  "store": {
    "book": [
      {
        "category": "reference",
        "author": "Nigel Rees",
        "title": "Sayings of the Century",
        "price": 8.95
      },
      {
        "category": "fiction",
        "author": "Evelyn Waugh",
        "title": "Sword of Honour",
        "price": 12.99
      },
      {
        "category": "fiction",
        "author": "Herman Melville",
        "title": "Moby Dick",
        "isbn": "0-553-21311-3",
        "price": 8.99
      },
      {
        "category": "fiction",
        "author": "J. R. R. Tolkien",
        "title": "The Lord of the Rings",
        "isbn": "0-395-19395-8",
        "price": 22.99
      }
    ],
    "bicycle": {
      "color": "red",
      "price": 199.95,
      "size": "24-inch",
      "safetyRated": true,
      "features": {
        "style": "mountain",
        "brakes": "disc"
      }
    }
  }
}

The example below shows how parts of a response can be deleted. This can be used to reduce the payload size if it contains items that are never used by the calling client.

Policy Options to Delete Selected Properties:

 <jsonTransform continueOnError="false" displayName="jsonTransform_policy_transform"
               enabled="true" name="JSONTranform" version="1"
               xmlns="http://www.infor.com/ion/api" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://www.infor.com/ion/api jsonTransform.xsd">
    <deletions>
        <delete path="$.store.book[1..2].price"/> <!-- delete 2nd and 3rd book -->
        <delete path="$.store.bicycle.color"/> <!-- delete color from bicycle -->
    </deletions>
</jsonTransform>

Adjusted Response after Deletions:

 {
  "store": {
    "book": [
      {
        "category": "reference",
        "author": "Nigel Rees",
        "title": "Sayings of the Century",
        "price": 8.95
      },
      {
        "category": "fiction",
        "author": "J. R. R. Tolkien",
        "title": "The Lord of the Rings",
        "isbn": "0-395-19395-8",
        "price": 22.99
      }
    ],
    "bicycle": {
      "price": 199.95,
      "size": "24-inch",
      "safetyRated": true,
      "features": {
        "style": "mountain",
        "brakes": "disc"
      }
    }
  }
}

The next example shows how sub-objects and properties can be added if missing from the document. The policy uses the JSONPaths to check if the objects/properties already exist in the document. If they already exist, those existing values are returned in the document untouched. If they do not exist, they are added to the document with the values you specify.

Policy Options to Add Default Values:

<jsonTransform continueOnError="false" displayName="jsonTransform_policy_transform"
               enabled="true" name="JSONTranform" version="1"
               xmlns="http://www.infor.com/ion/api" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://www.infor.com/ion/api jsonTransform.xsd">
    <deletions/> <!-- no deletions (but if there were any they would all be done before the any default values were added -->
    <defaultValues>
        <default path="$.store.bicycle.terms.warranty">1 year parts and labor</default>  <!-- add a simple property and value -->
        <default path="$.store.bicycle.contactInfo">
            <![CDATA[JSON{"email": "sales@infor.com", "phone": "678-319-8000"}]]> <!-- Note CDATA-wrapper and JSON{" syntax used to add and entire sub-object -->
        </default>
    </defaultValues>
</jsonTransform>

Adjust Response after Default Value Additions:

{
  "store": {
    "book": [
     ...  (book array is unchanged and omitted for the sake of brevity)
    ],
    "bicycle": {
      "color": "red",
      "price": 199.95,
      "size": "24-inch",
      "safetyRated": true,
      "features": {
        "style": "mountain",
        "brakes": "disc"
      },
      "terms": {
         "warranty": "1 year parts and labor"
      },
      "contactInfo": {
         "email": "sales@infor.com",
         "phone": "678-319-8000"
      }
    }
  }
}

This example shows how deletions, defaults, and full transformations can be combined. Note that all deletes are done before all default value additions and before any transformations.

Policy Options for Combined Delete, DefaultValue, and Transformation:

<jsonTransform continueOnError="false" displayName="jsonTransform_policy_transform"
               enabled="true" name="JSONTranform" version="1"
               xmlns="http://www.infor.com/ion/api" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://www.infor.com/ion/api jsonTransform.xsd">
    <deletions>
        <delete path="$.store.book[1].price"/> <!-- delete price from 2nd book -->
    </deletions>
    <defaultValues>
        <default path="$.store.bicycle.contactInfo">  <!-- add contactInfo sub-object if it does not already exist -->
            <![CDATA[JSON{"email": "sales@infor.com", "phone": "678-319-8000"}]]>
        </default>
    </defaultValues>
    <transformations>
        <transform><![CDATA[{   <!-- create an entirely new response document using selected bits and pieces of the original target response -->
            "allPrices": ["$.store..price"],            <!-- Build new array of just prices of everything in the store -->
            "contact": "$.store.bicycle.contactInfo",   <!-- Grab contactInfo object, but rename as contact -->
            "book3": "$.store.book[2]"                  <!-- Grab just 3rd book and rename it -->
      }]]></transform>
    </transformations>
</jsonTransform>

Adjusted Response after Delete, Default, and Transform:

{
  "allPrices": [8.95, 8.99, 22.99, 199.95],  (Only 4 prices since 2nd book price was deleted)
  "contact": {                               (contactInfo did not even exist in document until we used defaultValues to add it)
    "email": "sales@infor.com",
    "phone": "678-319-8000"
  },
  "book3": {
    "category": "fiction",
    "author": "Herman Melville",
    "title": "Moby Dick",
    "isbn": "0-553-21311-3",
    "price": 8.99
  }
}

Configuration

<jsonTransform> Attributes

<jsonTransform name="JSON transform example" displayName="jsonTransform" enabled="true" version="1.0">
Name Default Required Description
name n/a yes Name of this policy instance.
displayName Display name of this policy instance.
enabled true yes Indicates if the policy is enabled or not. If not enabled, the policy is ignored by the ION API Gateway.
version 1.0 yes Version of the policy.

Elements

Element Default Required Type Multiplicity
deletions n/a no container of 0..* <delete> child elements 0..1
defaultValues n/a no container of 0..* <default> child elements 0..1
transformation n/a no container of 0..* <transform> child elements 0..1

<delete> Element

Zero or more <delete> elements can appear under the <deletions> element.

Name

Type Required Description
path attribute, string yes JSONPath of the object/property/array-item in the document that is to be deleted.

<default> Element

Zero or more <default> elements can appear under the <defaultValues> element.

Name Type Required Description
path attribute, string yes JSONPath of the object/property/array-item in the document that should be checked for existence and created if it does not exist.
(element value) string yes number, true|false, string, or JSON{} sub-object enclosed in a <<[CDATA[ ... ]]> wrapper. This is the value that is added at the place indicated by the path if it does not already exist.

<transform> Element

Zero or more <transform> elements can appear under the <transformations> element.

Name Type Required Description
kind attribute, string no Kind of transformation to use. Choices are "handlebars" or "jsonpathObjectTransform". If omitted, the default is jsonpathObjectTransform.
output attribute, string no Value to use for response content-type header. For example. you can say "application/xml" if you are transforming JSON from the target into XML. If omitted, the content-type provided by the target server is used unchanged.
n/a CDATA string yes JSON template using JSONPath expressions describing how to build a new document from the original document.