1. REAL-WORLD JOLT PATTERNS
These patterns cover 95% of JSON transformation tasks.
Pattern 1 — Flattening deep JSON into simple key/value JSON
Input
{
"user": {
"profile": {
"name": "Alice",
"age": 30
},
"address": {
"city": "Dhaka",
"zip": "1000"
}
}
}
Spec
[
{
"operation": "shift",
"spec": {
"user": {
"profile": {
"name": "name",
"age": "age"
},
"address": {
"city": "city",
"zip": "zip"
}
}
}
}
]
Output
{
"name": "Alice",
"age": 30,
"city": "Dhaka",
"zip": "1000"
}
Pattern 2 — Flatten unknown dynamic keys
Input
{
"env": {
"JAVA_HOME": "/opt/java",
"PATH": "/bin:/usr/bin",
"USER": "root"
}
}
Spec
[
{
"operation": "shift",
"spec": {
"env": {
"*": "&" // & means “copy key name"
}
}
}
]
Output
{
"JAVA_HOME": "/opt/java",
"PATH": "/bin:/usr/bin",
"USER": "root"
}
Pattern 3 — Flatten Array of Objects → Map by ID
Very common in backend transformations.
Input
{
"products": [
{ "id": 1, "name": "Pen", "price": 10 },
{ "id": 2, "name": "Notebook", "price": 30 }
]
}
Spec
[
{
"operation": "shift",
"spec": {
"products": {
"*": {
"@": "productMap.@(1,id)"
}
}
}
}
]
Explanation
-
*→ iterate array -
@→ copy entire object -
@(1,id)→ read parent object’sidand use as map key
Output
{
"productMap": {
"1": { "id": 1, "name": "Pen", "price": 10 },
"2": { "id": 2, "name": "Notebook", "price": 30 }
}
}
Pattern 4 — Grouping items by category
Input
{
"items": [
{ "name": "Fish", "type": "Food" },
{ "name": "Apple", "type": "Food" },
{ "name": "Shirt", "type": "Clothes" }
]
}
Spec
[
{
"operation": "shift",
"spec": {
"items": {
"*": {
"@": "grouped.@(1,type)[]"
}
}
}
}
]
Explanation:
-
@(1,type)→ read the type dynamically -
[ ]→ append to array
Output
{
"grouped": {
"Food": [
{ "name": "Fish", "type": "Food" },
{ "name": "Apple", "type": "Food" }
],
"Clothes": [
{ "name": "Shirt", "type": "Clothes" }
]
}
}
Pattern 5 — Filter array items based on value
⚠ JOLT cannot do conditional filtering directly (no "if"),
BUT you can simulate filtering by mapping only the matching items.
Example: Keep only items where "active": true.
Input
{
"users": [
{ "id": 1, "name": "A", "active": true },
{ "id": 2, "name": "B", "active": false },
{ "id": 3, "name": "C", "active": true }
]
}
Spec
This keeps only active==true.
[
{
"operation": "shift",
"spec": {
"users": {
"*": {
"active": {
"true": {
"@2": "activeUsers[]"
}
}
}
}
}
}
]
Explanation
-
@2= go 2 levels up → the whole user object - Only items where
"active": "true"map successfully
Output
{
"activeUsers": [
{ "id": 1, "name": "A", "active": true },
{ "id": 3, "name": 3, "active": true }
]
}
Pattern 6 — Reorder and rename fields
Input
{
"id": 10,
"first": "Alice",
"last": "Wonder"
}
Spec
[
{
"operation": "shift",
"spec": {
"id": "user.id",
"first": "user.name.first",
"last": "user.name.last"
}
}
]
Output
{
"user": {
"id": 10,
"name": {
"first": "Alice",
"last": "Wonder"
}
}
}
Pattern 7 — Add default values
Spec
[
{
"operation": "default",
"spec": {
"status": "ACTIVE",
"roles": ["USER"]
}
}
]
Useful in user creation APIs.
Pattern 8 — Selective removal of fields
Spec
[
{
"operation": "remove",
"spec": {
"internalId": "",
"debug": ""
}
}
]
Pattern 9 — Math and string operations
Using modify-overwrite-beta.
Input
{
"price": 100,
"tax": 15
}
Spec
[
{
"operation": "modify-overwrite-beta",
"spec": {
"total": "=intSum(@(1,price), @(1,tax))"
}
}
]
Output
{
"price": 100,
"tax": 15,
"total": 115
}
Pattern 10 — Transform list of values to objects
Input
{
"tags": ["red", "blue", "green"]
}
Spec
[
{
"operation": "shift",
"spec": {
"tags": {
"*": {
"@": "list[]",
"$": "list[].name"
}
}
}
}
]
Output
{
"list": [
{ "name": "red" },
{ "name": "blue" },
{ "name": "green" }
]
}
2. INTERACTIVE EXAMPLES
These help you understand JOLT step-by-step.
Interactive Example 1: Dynamic key renaming
Input
{
"meta": {
"user_id": 5,
"user_role": "admin"
}
}
Goal
Convert keys from snake_case → camelCase.
Spec
[
{
"operation": "shift",
"spec": {
"meta": {
"user_*": "user.&(0,1)"
}
}
}
]
Explanation:
-
user_*matches → user_id, user_role -
&(0,1)takes the part after the underscore- id
- role
Output
{
"user": {
"id": 5,
"role": "admin"
}
}
Interactive Example 2: Pick fields based on dynamic index
Input
{
"data": [
{ "name": "A", "score": 80 },
{ "name": "B", "score": 90 }
]
}
Want → convert list to key/value
Spec
[
{
"operation": "shift",
"spec": {
"data": {
"*": {
"score": "scores.@(2,name)"
}
}
}
}
]
Explanation:
@(2,name) goes 2 levels up → reads the "name"
Output
{
"scores": {
"A": 80,
"B": 90
}
}
Interactive Example 3 — Conditional grouping by value
Input
{
"items": [
{ "name": "Book", "type": "A", "price": 20 },
{ "name": "Pen", "type": "B", "price": 5 },
{ "name": "Bag", "type": "A", "price": 100 }
]
}
Spec
[
{
"operation": "shift",
"spec": {
"items": {
"*": {
"@": "group.@(1,type)[]"
}
}
}
}
]
Output
group:
A:
- Book
- Bag
B:
- Pen
Top comments (0)