Execution sequence
The JSON to JSON transformer executes operations in a strict sequence to ensure proper data transformation from input JSON to target API request structure.
The transformation engine operates in the following execution order:
- shift: Mandatory first step.
- default: Mandatory second step.
- Custom operations can run in any order.
- ModifyArrayObjects.
- DefaultIfInputMissing.
- FilterArray.
- SpreadArray.
shift operation
The shift operation performs the initial structural mapping from the input JSON format to the target API request structure. It transforms source data elements into their corresponding destination paths within the output JSON.
This operation creates the foundation required by all subsequent transformation steps.
- Maps values from source paths in the input to destination paths in the output.
- Uses wildcards (*) to process array elements dynamically.
- Supports reference notations (@(2,value)) to access sibling or parent values.
- Establishes the base structure to use in the API request.
- Establishes the initial API object structure.
- Creates all necessary paths required by later operations.
- Without this step, downstream updates would fail due to missing target paths.
- Sets up the baseline transformation that other operations build upon.
For more information, see shift operation.
The following sample JSON template provides an example to help you understand the key mappings:
{
"operation": "shift",
"spec": {
"conditions": {
"*": {
"key": {
"Status": {
"@(2,value)": "API.Input.Order.OrderStatus.Status"
},
"SelectMethod": {
"@(2,value)": "API.Input.Order.SelectMethod"
}
}
}
},
"newChanges": {
"*": {
"key": {
"Name": {
"@(2,value)": "API.Input.Order.OrderBy.Attribute.Name"
},
"OrderName": {
"@(2,value)": "API.Input.Order.OrderStatus.Name"
}
}
}
},
"dataProfiles": {
"0": "API.DataProfile"
}
}
}The following mappings correspond to the sample input JSON structure shown in the example. Actual field names and paths vary based on the specific JSON schema.
conditions[*].key.Status=API.Input.Order.OrderStatus.Status.conditions[*].key.SelectMethod=API.Input.Order.SelectMethod.newChanges[*].key.Name=API.Input.Order.OrderBy.Attribute.Name.newChanges[*].key.OrderName=API.Input.Order.OrderStatus.Name.dataProfiles[0]=API.DataProfile.
default operation
The default operation initializes static and fallback values in a non-destructive way. Unlike shift, which maps data from input, default walks through the specification and adds missing values to the output structure.
- The shift operation asks where the input data should go.
- The default operation asks whether the data exists. If not, it adds the data.
The target API schema must be provided to the default operation. This operation requires following details:
- The API expected structure, including field names, nesting, and types.
- Required default values to use in missing fields.
- Any static values that should always be present.
- Analyze the target API schema and know exactly what fields are required.
- Map those requirements into the default specification.
- Set appropriate defaults for each field based on the API needs.
ModifyArrayObjects custom operation
The ModifyArrayObjects operation dynamically updates leaf values inside arrays by matching conditions and extracting sibling values. It allows data-driven injection without hardcoding values.
This custom operation is not part of standard JOLT. It enables complex transformations that involve the following tasks:
- Navigating nested array structures.
- Extracting values based on dynamic conditions.
- Injecting data into specific array positions.
- Building complex query structures programmatically.
- Scans source arrays, such as conditions[] or newChanges[].
- Matches patterns based on specified conditions.
- Extracts sibling values from matched objects.
- Injects values into target array positions.
- Operates non-destructively and only adds or updates specific values.
- First ModifyArrayObjects
- Behavior
- Reads values from conditions[*].
- Updates query filters dynamically:
usereEmail.EmailID=API.Input.Order.ComplexQuery.And.Or.Exp[0].Value.key.UserName=API.Input.Order.ComplexQuery.And.Or.Exp[1].Value.
- Maps
newChanges[*].key.NametoAPI.Input.Order.ComplexQuery.And.Or.Exp[0].Value2.
- Second ModifyArrayObjects
- Behavior
Injects additional sibling values:
myEmail.EmailID=API.Input.Order.ComplexQuery.And.Or.Exp[0].Value1.key.MyUserName=API.Input.Order.ComplexQuery.And.Or.Exp[1].Value1.
- Multiple ModifyArrayObjects operations can be chained.
- Each instance focuses on a specific transformation responsibility.
- You can use the simple class name ModifyArrayObjects in spec JSON. The name is automatically mapped to the fully qualified name.
DefaultIfInputMissing custom operation
The DefaultIfInputMissing operation ensures that mandatory fields are always populated. It acts as a safety net after all dynamic updates are applied.
This custom operation provides a final layer of validation and completeness. It operates on the principle of fail-safe defaults and ensures that critical fields always have values, even when source data is incomplete or missing.
- Checks specific input paths for existence or null values.
- Compares against target output paths where values should be.
- Applies predefined defaults only when the target is missing or empty.
- Never overwrites values that are already set by previous operations.
- Runs last in the transformation chain to use maximum safety.
The following sample spec JSON template provides an example of the spec template JSON structure to help you understand the key mappings:
{
"operation": "DefaultIfInputMissing",
"spec": {
"rules": [
{
"inputKey": "newChanges.*.key.OrderName",
"outputPath": "API.Input.Order.OrderStatus.Name",
"defaultValue": "DEFAULT_ORDER_NAME"
},
{
"inputKey": "conditions.*.key.SelectMethod",
"outputPath": "API.Input.Order.SelectMethod",
"defaultValue": "LOCK"
},
{
"inputKey": "conditions.*.key.UserName",
"outputPath": "API.Input.Order.ComplexQuery.And.Or.Exp[1].Type",
"defaultValue": "FLIKE"
}
]
}
}Key mappings explained
The following mappings correspond to the sample input JSON structure shown in the example. Actual field names and paths vary based on the specific JSON schema.
| Input Key | Output Path | Default Value |
|---|---|---|
| newChanges.*.key.OrderName | API.Input.Order.OrderStatus.Name | DEFAULT_ORDER_NAME |
| conditions.*.key.SelectMethod | API.Input.Order.SelectMethod | LOCK |
| conditions.*.key.UserName | API.Input.Order.ComplexQuery.And.Or.Exp[1].Type | FLIKE |
- Checks if the input path exists.
- Applies the default only when the input is missing.
- Never overrides existing values.
- You can use the simple class name
DefaultIfInputMissingin spec JSON. The name is automatically mapped to the fully qualified name.
FilterArray custom operation
- Filters array elements based on specified conditions, keeping only elements that match the criteria.
- It compacts all object properties from an array into one object.
Evaluates each array element against a condition and removes elements that don't match.
Following is a sample spec JSON template for reference.
{
"operation": "FilterArray",
"spec": {
"array": "API.FilterCondn.tempArray",
"condition": {
"key": "id",
"oper": "GT",
"value": 1
}
}
}- Null checks
-
NOT_NULL: Checks if the value is not null.
- Boolean checks
-
TRUE: Checks if the value is true.FALSE: Checks if the value is false.
- List membership
-
IN: Checks if the value exists in a list. The value parameter should be a list.NOT_IN: Checks if the value does not exist in a list. The value parameter should be a list.
- Regular expression
-
REGEX: Matches the value against a regex pattern.
- Numeric comparisons
-
The operation attempts numeric parsing first.
GT: Greater than.GTE: Greater than or equal to.LT: Less than.LTE: Less than or equal to.EQ: Equal to. Works with both numeric and string values.NE: Not equal to. Works with both numeric and string values.
- String comparisons
-
The operation uses string comparison as a fallback if the value is not numeric.
EQ: Equals. Performs an exact string match.NE: Not equals.CONTAINS: String contains substring.STARTS_WITH: String starts with prefix.ENDS_WITH: String ends with suffix.
Before
[
{
"id": 1,
"pass": false,
"a": "b"
},
{
"id": 2,
"pass": true,
"a": "d"
},
{
"id": 3,
"pass": false,
"e": "f"
}
]After: with condition id > 1
[
{
"id": 2,
"pass": true,
"a": "d"
},
{
"id": 3,
"pass": false,
"e": "f"
}
]
SpreadArray custom operation
The SpreadArray operation converts an array of multiple objects into a single object by merging all properties from all array elements.
This operation takes an array, extracts all objects from it, and merges their properties into one consolidated object that replaces the original array.
{
"operation": "SpreadArray",
"spec": {
"array": "API.foo"
}
}
Before
{
"API": {
"foo": [
{"id": 1, "name": "John"},
{"age": 25, "city": "NYC"},
{"status": "active"}
]
}
}After
{
"API": {
"foo": {
"id": 1,
"name": "John",
"age": 25,
"city": "NYC",
"status": "active"
}
}
}What happens
- Takes the specified array, such as API.foo.
- Extracts all objects from the array.
- Merges all properties into a single object.
- Replaces the array with the merged object at the same path.
SpreadArray in spec JSON. The name is
automatically mapped to the fully qualified name.