Payload Types

Processors in an integration flow send and receive data as strings, binary data, or JSON compliant objects. In most cases, you do not need to know which processors use which payload types. The flow-server often converts data automatically to the most suitable type as it passes from one processor to the next. Knowing the types matters when you transform a payload manually or when a processor can work with more than one type.

To convert a payload, see Payload Conversions.

JSON Compliant

The default format for payloads is an instance of a Java Map<String, *> or List<Map<String, *>>, where the field types are compatible with JSON standards. Properties are limited to strings, numbers, booleans, lists or arrays, and other JSON compliant objects. Because of these rules, you can treat a payload as regular JSON, which makes it easier to map data and to convert to and from other JSON compliant objects.

When appropriate, a processor automatically produces a JSON compliant object as its output, uses one as its internal data format, or both. For example, a dbStatement processor produces a JSON compliant object or array, and you can configure it to interpret an incoming payload as JSON.

XML Compliant

The flow-server can also represent XML data in a JSON compliant format. XML compliant JSON objects must follow formatting rules so that they capture the XML declaration, namespaces, attributes, and text. These rules make it possible to convert JSON compliant objects to XML, and they keep the processing of incoming XML data consistent.

For example, a soapApi processor for SOAP endpoints might receive the following XML input:

<SayHi xmlns="http://www.bccs.uib.no/EchoService.wsdl" xmlns:aa="http://www.bccs-aa.uib.no/EchoService.wsdl">
    <Hi>hi, it's john</Hi>
    <Hi from="jane">hello</Hi>
    <aa:Hi>
        <aa:Greeting>well, hi</aa:Greeting>
        <aa:Speaker>janice</aa:Speaker>
    </aa:Hi>
    <Message xmlns="http://www.bccs-bb.uib.no/EchoService.wsdl">
        <![CDATA[
            Dear Jim,

            What's up?
        ]]>
    </Message>
</SayHi>

The flow-server converts the data to the following JSON compliant object for the next processor to use:

{
  "_declaration": {
    "version": "1.0",
    "standalone": "no"
  },
  "ns1_SayHi": {
    "ns1_Hi": [
      {
        "_text": "hi, it's john"
      },
      {
        "_attributes": {
          "from": "jane"
        },
        "_text": "hello"
      }
    ],
    "ns2_Hi": [
      {
        "ns2_Greeting": {
          "_text": "well, hi"
        },
        "ns2_Speaker": {
          "_text": "janice"
        }
      }
    ],
    "ns3_Message": {
      "_cdata": "\n    Dear Jim,\n\n    What's up?\n    "
    }
  },
  "_xmlns": {
    "ns1": "http://www.bccs.uib.no/EchoService.wsdl",
    "ns2": "http://www.bccs-aa.uib.no/EchoService.wsdl",
    "ns3": "http://www.bccs-bb.uib.no/EchoService.wsdl"
  }
}

This example uses three XML namespaces. The _xmlns property lists them, and each one gets an incremental ns prefix. The <SayHi> and <Hi> elements belong to the first namespace, so you access them as ns1_SayHi and ns1_Hi in the object.

Only one <aa:Hi> element is present, but the ns2_Hi property is still an array because the XML schema for these elements defines a maxOccurs greater than one. Without a schema, the converter assumes the following:

  • Multiple adjacent elements with the same name are an array.

  • A single element with no like siblings is a regular object.

To avoid ambiguity, use an XML schema.

The text content of an element is in a child _text property. CDATA content goes in a _cdata property instead. Elements that have attributes also get an _attributes property. The following table compares an XML element with its JSON form:

XML JSON
<Hi from="jane">hello</Hi>
"ns1_Hi": [
  {
    "_attributes": {
      "from": "jane"
    },
    "_text": "hello"
  }
]

Namespace Mapping

To replace the auto-generated ns prefixes, map each namespace to a prefix of your own. The elements of a namespace mapped to _default get no prefix. The examples below map the first two namespaces above, ns1 and ns2, to _default and aa.

On soapApi, list the mappings in its namespacePrefixMapping property:

soapApi {
    id = "soap-echo-api"
    wsdlSpecId = soapResourceKey.toResourceIdentifier()
    serviceName = "EchoService"
    portName = "EchoService"
    namespacePrefixMapping = """
        _default = http://www.bccs.uib.no/EchoService.wsdl
        aa = http://www.bccs-aa.uib.no/EchoService.wsdl
    """.trimIndent()
}

On any other processor, call namespacePrefix once for each namespace, in fromXmlText inside the processor’s inboundTransformationStrategy:

inboundTransformationStrategy {
    fromXmlText {
        schemaId = "XSD:echo-service:1"
        namespacePrefix("_default", "http://www.bccs.uib.no/EchoService.wsdl")
        namespacePrefix("aa", "http://www.bccs-aa.uib.no/EchoService.wsdl")
    }.toJsonCompliant()
}

Conversion by Format describes the inboundTransformationStrategy and the other options of fromXmlText.

Either configuration converts the XML to the following JSON compliant object. The third namespace has no mapping, so it gets the auto-generated prefix ns1:

{
  "_declaration": {
    "version": "1.0",
    "standalone": "no"
  },
  "SayHi": {
    "Hi": [
      {
        "_text": "hi, it's john"
      },
      {
        "_attributes": {
          "from": "jane"
        },
        "_text": "hello"
      }
    ],
    "aa_Hi": [
      {
        "aa_Greeting": {
          "_text": "well, hi"
        },
        "aa_Speaker": {
          "_text": "janice"
        }
      }
    ],
    "ns1_Message": {
      "_cdata": "\n    Dear Jim,\n\n    What's up?\n    "
    }
  },
  "_xmlns": {
    "_default": "http://www.bccs.uib.no/EchoService.wsdl",
    "aa": "http://www.bccs-aa.uib.no/EchoService.wsdl",
    "ns1": "http://www.bccs-bb.uib.no/EchoService.wsdl"
  }
}

Outbound XML

Data for a soapRequest processor, or the response in a soapApi flow, must follow the same XML compliant JSON format. The following example shows a simplified version of that format:

{
  "_xmlns": {
    "_default": "namespace_1",
    "other": "namespace_2"
  },
  "Element_Name": { // namespace_1
    "Child_Element": {
      "_text": "value"
    }
  },
  "other_Element": { // namespace_2
    "_text": "value"
  }
}

The processor then interprets the data and converts it to valid XML.

Strings

Some processors produce a string instead of a JSON compliant object. A restRequest processor, for example, makes an external request to a REST API and returns the response as a string. Even when the API is JSON-based, the payload is still a string that holds JSON.

If restRequest is the last processor in the flow, the client interprets the string correctly. However, if you need to process the data further, note that not every processor automatically converts the string to a JSON compliant object. Processors such as map and dbStatement work with strings, so automatic conversion isn’t always wanted. In such cases, you can convert the incoming payload manually with an inboundTransformationStrategy sub-builder. For details, see Payload Conversions.

Binary

Some processors and flow sources produce binary data. A readFiles inbound endpoint, for example, returns a text file’s contents as a binary byte string.

In most cases, it does not matter that the data is binary. A restRequest processor still understands the data and converts it to a JSON compliant object. Other processors, such as dbStatement, need a hint first, in the form of an inboundTransformationStrategy sub-builder. For details, see Payload Conversions.

Binary Serialization

A processor can receive or send binary data in a serialization format, such as Avro. Conversion by format converts such data to and from a JSON compliant object. The payload formats table lists the serialization formats it supports.