Skip to content

Transform Connector

The Transform connector adds or replaces payload fields by evaluating a list of rules. Each rule produces one output key using one of three expression types: JSONPath, Go text/template, or a static literal.

Connector Type: MeddleTransform

{
"type": "MeddleTransform",
"config": {
"dropOriginal": false,
"rules": [
{ "outputKey": "temperature", "type": "jsonpath", "expression": "$.sensor.temperature" },
{ "outputKey": "summary", "type": "template", "expression": "{{ .sensor_id }}: {{ .status }}" },
{ "outputKey": "data_source", "type": "static", "expression": "edge-gateway-01" }
]
}
}
  • rules (required, min 1): Ordered array of transform rules
  • dropOriginal: When true, only the rule outputs are emitted; the source payload is discarded. Default false — source fields are preserved and rule outputs overlay them.
  • outputKey (required): Payload key the rule writes to
  • type (required): jsonpath, template, or static
  • expression (required): Type-specific expression

type: "jsonpath" evaluates a JSONPath expression against the payload (marshalled to JSON internally). Use this for extracting nested values.

{ "outputKey": "first_metric", "type": "jsonpath", "expression": "$.metrics[0].value" }

Common patterns:

$.field – top-level field
$.sensor.temperature – nested field
$.metrics[0].value – first array element
$.metrics[*].name – array projection

type: "template" runs a Go text/template against the payload. Payload fields are accessible as {{ .field }}. The result is always a string.

{ "outputKey": "label", "type": "template", "expression": "{{ .device }}/{{ .channel }}" }
{{ .temperature }} – substitution
{{ if gt .pressure 100.0 }}HIGH{{ else }}OK{{ end }} – conditional
Sensor {{ .id }} reports {{ printf "%.2f" .value }} – formatting

type: "static" writes the literal expression string to outputKey on every payload. Use for tags, source markers, or pipeline IDs.

{ "outputKey": "source", "type": "static", "expression": "field-gateway" }

When dropOriginal: true, the connector emits only the rule outputs and discards every input field. Use this to project a payload down to a minimal shape.

{
"type": "MeddleTransform",
"config": {
"dropOriginal": true,
"rules": [
{ "outputKey": "ts", "type": "jsonpath", "expression": "$.timestamp" },
{ "outputKey": "value", "type": "jsonpath", "expression": "$.metrics[0].value" }
]
}
}
  1. Extract a nested field to the top level for downstream connectors
  2. Build a human-readable summary string for notifications
  3. Tag payloads with a pipeline or source identifier
  4. Reshape a verbose protocol payload into a slim downstream schema
{
"type": "MeddleTransform",
"config": {
"dropOriginal": false,
"rules": [
{ "outputKey": "device_id", "type": "jsonpath", "expression": "$.metadata.deviceId" },
{ "outputKey": "temperature", "type": "jsonpath", "expression": "$.readings.temp" },
{ "outputKey": "alert_text", "type": "template", "expression": "Device {{ .device_id }} at {{ .temperature }}°C" },
{ "outputKey": "env", "type": "static", "expression": "production" }
]
}
}

Note that alert_text references device_id — earlier rules’ outputs are not visible to later rules within the same Transform pass, so {{ .device_id }} refers to the original payload key only if it already exists upstream. Chain two Transform connectors when you need staged composition.

  • Use JSONPath when extracting structured values; use template for string composition; use static for constants
  • Prefer Transform over Script when the logic is just extraction or formatting — it is faster and easier to audit
  • Use dropOriginal: true to enforce a strict downstream schema
  • Validate JSONPath expressions upfront — invalid paths surface as runtime errors on the error channel
  • Reshape - Direct key renaming
  • Script - Sandboxed Lua for complex logic
  • Filter - Whitelist/blacklist keys
  • Validation - Enforce field types and ranges