Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Marshal and Unmarshal

Marshal and Unmarshal are the Message Translator pair (Hohpe & Woolf). Marshal serializes the body to a named wire format. Unmarshal deserializes a wire-format body back into a structured type. Together they cross the boundary between the pipeline and external systems.

    let route_csv_marshal = RouteBuilder::from("timer:csv-marshal?period=2000&repeatCount=3")
        .route_id("csv-marshal")
        .set_body(r#"[{"name":"Carol","age":28},{"name":"Dave","age":35}]"#)
        .unmarshal("json")?
        .log("Route 2: starting CSV marshal from Json", LogLevel::Info)
        .marshal("csv")?
        .log("Route 2: marshalled Json -> CSV Text", LogLevel::Info)
        .to("log:info?showBody=true")
        .error_handler(ErrorHandlerConfig::log_only())
        .build()?;
    let route_json_roundtrip = RouteBuilder::from("timer:json-roundtrip?period=2000&repeatCount=3")
        .route_id("json-roundtrip")
        .set_body(r#"{"message": "hello", "count": 42}"#)
        .log(
            "Route 1: Starting with Text body containing JSON string",
            LogLevel::Info,
        )
        .unmarshal("json")?
        .log("Route 1: Unmarshalled Text -> Json", LogLevel::Info)
        .marshal("json")?
        .log(
            "Route 1: Marshalled Json -> Text (round-trip complete!)",
            LogLevel::Info,
        )
        .to("log:info?showBody=true")
        .error_handler(ErrorHandlerConfig::log_only())
        .build()?;
YAML equivalent
- id: json-roundtrip
  from: timer:json-roundtrip?period=2000&repeatCount=3
  error_handler:
    retry:
      max_attempts: 0
  steps:
    - set_body:
        value: '{"message": "hello", "count": 42}'
    - unmarshal: json
    - marshal: json
    - to: log:info?showBody=true

- id: csv-marshal
  from: timer:csv-marshal?period=2000&repeatCount=3
  error_handler:
    retry:
      max_attempts: 0
  steps:
    - set_body:
        value: '[{"name":"Carol","age":28},{"name":"Dave","age":35}]'
    - unmarshal: json
    - marshal: csv
    - to: log:info?showBody=true

The .marshal("csv") call names the wire format as a string. The processor looks up that name in the data format registry and applies the format to the current body. Marshal stores the serialized result on the exchange. Unmarshal reverses the flow. It parses the body through the named format and stores the parsed structure on the exchange.

The string parameter keeps the route declaration format-agnostic. Common formats include json, csv, xml, and protobuf. Each format owns its body-type mapping and its configuration. See Data Formats for the format catalog, the DataFormat trait, and per-format options. This page covers only the route-level step.

A route that crosses a system boundary pairs the two steps. Marshal prepares the body for the wire on the outgoing side. Unmarshal restores a structured type on the incoming side. Each step in between then reads the body shape it expects.

Per ADR-0001, both steps compile into Service<Exchange> services in the Tower middleware pipeline. The data format registry and the marshal/unmarshal hooks are documented in camel-processor/CONTEXT.md.

The example sources are at examples/marshal-csv and examples/marshal-unmarshal.