Skip to main content

Scenario

This guide uses the classic Pet Store example to build a fully enriched output JSON by combining the following sources:
  • Request body fields (JSONPath)
  • Two request headers (Content-Type, X-Request-Id)
  • A query parameter (format)
  • Context variables (HTTP method, client IP, correlation ID, year, date-time, environment)
  • JEXL ternary expressions (conditional operation type, computed summary)
  • Custom intermediate variables (petName, categoryLabel, statusLabel, nestedObject)

Input Request

{
  "id": 1,
  "category": { "id": 10, "name": "Canine" },
  "name": "Buddy",
  "photoUrls": ["https://example.com/buddy.jpg"],
  "tags": [{ "id": 5, "name": "friendly" }],
  "status": "available"
}

Step 1: Extract Intermediate Custom Variables

Row 1 — Pet Name

FieldValue
Build ModeTemplate
Template#{body.$.name}
TargetCustom Variable → petName
Default Valueunknown

Row 2 — Category Label

FieldValue
Build ModeTemplate
Template#{body.$.category.name}
TargetCustom Variable → categoryLabel
Default Valueuncategorized

Row 3 — Status Label

FieldValue
Build ModeTemplate
Template#{body.$.status == 'available' ? 'AVAILABLE' : body.$.status == 'pending' ? 'PENDING' : 'SOLD'}
TargetCustom Variable → statusLabel
Default ValueUNKNOWN

Step 2: Conditional Nested Object

Row 4 — Default (null)

FieldValue
Build ModeTemplate
Templatenull
TargetCustom Variable → nestedObject

Row 5 — Available Status Override

FieldValue
Row Conditionrequest.body.$.status == 'available'
Build ModeTemplate
Template{"displayName":"#{petName} - #{categoryLabel}","statusLabel":"#{statusLabel}"}
TargetCustom Variable → nestedObject
The template above contains { and } characters, which are nested curly braces inside the #{} expression block. The balanced brace scanner in the Message Builder correctly handles this without breaking the parsing.

Step 3: Final Body Template

Row 6 — Build Enriched JSON

{"request":{"headers":{"contentType":"#{header.Content-Type}","xRequestId":"#{header.X-Request-Id}"},"query":{"format":"#{query.format}"},"body":{"id":#{body.$.id},"name":"#{petName}","category":{"id":#{body.$.category.id},"name":"#{categoryLabel}","nested":#{nestedObject}},"photoUrls":#{body.$.photoUrls},"tags":#{body.$.tags},"status":"#{body.$.status}"}},"context":{"httpMethod":"#{context.request.httpMethod}","clientIp":"#{context.request.remoteAddress}","correlationId":"#{context.message.correlationId}","year":"#{context.system.year}","dateTime":"#{context.system.dateTime}","environment":"#{context.environment.name}"},"computed":{"operationType":"#{context.request.httpMethod == 'POST' ? 'create' : context.request.httpMethod == 'PUT' ? 'update' : context.request.httpMethod == 'DELETE' ? 'delete' : 'read'}","summary":"#{petName} (#{categoryLabel}) - #{statusLabel}"}}
FieldValue
Build ModeTemplate
TemplateTemplate above
TargetCustom Variable → enrichedPayload
Default Value{}

Expected Output

{
  "request": {
    "headers": {
      "contentType": "application/json",
      "xRequestId": "abc-123"
    },
    "query": {
      "format": "full"
    },
    "body": {
      "id": 1,
      "name": "Buddy",
      "category": {
        "id": 10,
        "name": "Canine",
        "nested": {
          "displayName": "Buddy - Canine",
          "statusLabel": "AVAILABLE"
        }
      },
      "photoUrls": ["https://example.com/buddy.jpg"],
      "tags": [{ "id": 5, "name": "friendly" }],
      "status": "available"
    }
  },
  "context": {
    "httpMethod": "POST",
    "clientIp": "192.168.1.1",
    "correlationId": "8260e8b4-29d7-479a-8266-5dbb29c0d0fa",
    "year": "2026",
    "dateTime": "2026-02-20T10:35:48.000Z",
    "environment": "production"
  },
  "computed": {
    "operationType": "create",
    "summary": "Buddy (Canine) - AVAILABLE"
  }
}

Key Points

TopicNote
Number fieldsDo not wrap in quotes: "id":#{body.$.id}
Array fieldsDo not wrap in quotes: "photoUrls":#{body.$.photoUrls}
Conditional JSON objectManage via custom variable + row condition
Custom variable referencesUse directly: #{petName}, #{statusLabel}
Nested {}The balanced brace scanner handles them correctly
Define intermediate custom variables first, then use them in the final template. This approach keeps the template clean and maintainable.