Skip to content

Transform processors

pkg/processor/transform.go defines the small Message Translator EIP processors that read and mutate the exchange body, headers, and properties via an expression. The default expression engine is Starlang (see the Starlang guide).

These primitives back the YAML keywords transform, set-header, set-body, remove-header, and log.

Processors in this file

NewTransform

Replaces the message body with the result of an expression. Implements the Message Translator EIP.

steps:
  - transform:
      starlang: |
        %sl 2.0
        output application/json
        input payload
        ---
        upper(payload)
Field Type Default Description
starlang string required Full Starlang program (header + --- + body). Set on transform, transform.starlang-file, or via a reusable process: { ref: ... }.

Constructor: NewTransform(expr engine.Expression) *Transform. The expression's evaluation result is written to ex.In().SetBody(...).

NewSetHeader

Sets a header to the result of an expression.

steps:
  - set-header:
      name: X-Trace-Id
      starlang: property("HelixWorkflowId")
Field Type Default Description
name string required Header name.
starlang string one of Starlang expression — evaluated per exchange.
constant string one of Static value — bypasses expression evaluation.

Constructor: NewSetHeader(name string, expr engine.Expression) *SetHeader.

NewSetBody

Replaces the message body with the result of an expression — equivalent to NewTransform but with a different YAML keyword to read more naturally in routes that construct a payload rather than transform one.

steps:
  - set-body:
      starlang: |
        %sl 2.0
        output application/json
        ---
        { "ok": true, "ts": now() }
Field Type Default Description
starlang string one of Starlang expression yielding the new body.
constant string one of Static string body.

NewRemoveHeader

Removes a single header by name. Use RemoveHeaders for glob matching.

steps:
  - remove-header: X-Internal-Token
Field Type Default Description
(string body) string required Header name to remove.

Constructor: NewRemoveHeader(name string) *RemoveHeader.

NewLog

Writes a structured log line at the chosen level. The message supports a focused set of placeholders, resolved against the exchange at runtime: ${header.NAME}, ${property.NAME}, ${body} and ${exchangeId} (unknown tokens are left untouched, so load-time ${ENV} substitution still passes through). showBody controls whether the In body is attached as a log field. For richer logging (MDC, headers/properties, custom formatters) see LogEIP.

steps:
  - log:
      message: "loaded ${header.HelixXlsxRowCount} rows from ${header.HelixXlsxSheet}"
      level: INFO
      showBody: false        # keep the line terse — don't echo the payload
Field Type Default Description
message string required Log message. Supports the Simple-language tokens ${header.NAME}, ${property.NAME}, ${body}, ${exchangeId}, resolved at runtime. Unknown ${…} tokens pass through unchanged.
level string INFO One of DEBUG, INFO, WARN, ERROR.
showBody boolean true Attach the In message body as a body= log field. Set false to keep the line terse — e.g. large streaming batches or PII.

Constructor: NewLog(message string, level slog.Level) *Log — defaults ShowBody: true; set the field to override. Runtime interpolation is provided by ExpandSimple (see simple.go).

Note: this is the full extent of Simple-language support — no OGNL body navigation (${body.field}), predicates, ${bean:…} or arithmetic. For computed values use a set-header/set-body Starlang expression upstream.

ConstantExpression

A trivial engine.Expression implementation that always returns the same value. Used by the reifier when YAML specifies constant: instead of starlang: on a set-header, set-body, or set-property step. Not a processor itself, but exposed so user code constructing routes in Go can pass a literal where an expression is expected.

Examples

workflows:
  - id: prep-payload
    trigger: { uri: direct://in }
    steps:
      - set-header:
          name: X-Trace-Id
          starlang: property("HelixWorkflowId")
      - transform:
          starlang: |
            %sl 2.0
            output application/json
            input payload
            ---
            { "wrapped": payload, "ts": now() }
      - log: { message: "wrapped", level: INFO }
      - target: kafka://outbound

Source

pkg/processor/transform.go

See also