JSON parser and domain

JSON (JavaScript Object Notation) is a simple data-interchange format based on a subset of the JavaScript programming language.

IBM® App Connect Enterprise supports a JSON domain. Messages in the JSON domain are processed by the JSON parser and serializer. The JSON parser interprets a bit stream by using the JSON grammar, and generates a corresponding JSON domain logical message tree. When processing data for output, the JSON serializer generates a JSON formatted bit stream from a JSON domain logical message tree.

JSON messages can be validated against a JSON schema file or OpenAPI definition during parsing. JSON message trees can be validated against a JSON schema file or OpenAPI definition during writing or mid-flow.

You can use the JSON editor in the IBM App Connect Enterprise Toolkit to edit JSON files; however, the validation capability of the editor has a number of limitations and should not be used to validate your JSON documents. For information about how to validate JSON documents, see JSON validation.

JSON is a language-independent text format, based on two structures:
  • Objects (name-value pairs) with the following types:
    • String
    • Number
    • Boolean
    • Null
  • Ordered collections of values (arrays)
Objects and arrays can be nested.

The JSON parser accepts only a JSON object or a JSON array as the top-level value type in both an input bit stream and an output bit stream. It is not possible to use the JSON parser to output a JSON string literal, number, Boolean, or null value without first embedding it in an object or array.

For more information about JSON message structure, see JSON message details. For more information about JSON parser parameters, see Parameter values for the JSON parser.

JSON data streams can be parsed from any coded character set ID (CCSID) that is supported by the integration node. The data stream is parsed according to the CCSID that is defined by the transport when the JSON parser is invoked from an input or request node, or defined by the CCSID parameter in a PARSE clause on a CREATE function call. If no CCSID is specified, or if a value of 0 is set, the parser attempts to detect (by examining the first few bytes of the data stream) whether one of the following Unicode encodings is being used:
  • UTF-8
  • UTF-16BE
  • UTF-16LE
  • UTF-32BE
  • UTF-32LE

If a UTF-* CCSID is explicitly specified, the JSON parser tolerates the corresponding Byte Order Mark (BOM) at the beginning of the data stream.

JSON data streams are parsed into a logical message tree under the Data element below the JSON parser root. The logical tree structure is shown in the Example JSON message.

The Data element can be accessed and manipulated from ESQL as JSON.Data, from Java™ as JSON/Data, from the Graphical Data Mapping editor by using the Add User-Defined function to define JSON->Data, or from XPath as $Body/Data. The JSON parser issues an error if a bit stream is not formatted according to the JSON grammar.

The JSON serializer serializes message trees into a JSON format data stream. The CCSID can be defined by either the integration node properties tree, or by transport headers in the message assembly. If no CCSID is defined, the serializer defaults to the queue manager default CCSID for all nodes except HTTP nodes, which default to UTF-8 encoding.

When the JSON serializer is invoked through an ASBITSTREAM function call, the CCSID is defined by the CCSID parameter. If no CCSID parameter is provided, or if the value is set to 0, the JSON serializer defaults to using UTF-8 encoding.

If you code the ASBITSTREAM function with the parser mode option set to FolderBitStream to parse a JSON domain message tree to a bit stream, the generated bit stream is a JSON format that is built from the target element and its children.

To process messages with the JSON parser, select JSON as the Message Domain on the relevant node in the message flow. The XSLTransform node does not support the JSON domain.

The integration node sets the HTTP Content-Type header to application/json when it serializes a JSON message tree, unless an explicit value is set by the message flow.

JSON objects are modeled in the integration node message tree as a sequence of NameValue elements. The parser builds the message tree in the order in which it encounters the members in the bit stream. The serializer writes the object members into the bit stream in the tree order.

JSON arrays are modeled in the integration node message tree as a Name element with a JSON parser-specific type flag of JSON.Array and ordered children. The children can be any of the following types of array:
  • An array that contains simple values; for example:
    "array1" : [ "thing1", 1 ]
    The following message tree is produced:
    (0x01001000:Array): array1 = (  
        (0x03000000:NameValue):Item = 'thing1' (CHARACTER)
        (0x03000000:NameValue):Item = 1 (INTEGER)
     )

    The JSON parser assigns the name Item to the NameValue elements.

  • An array that contains objects; for example:
    "array2" : [ {"a" : 1}, {"b" : 2} ]
    The following message tree is produced:
    (0x01001000:Array):array2 = (
      (0x01000000:Object):Item = (
        (0x03000000:NameValue):a = 1 (INTEGER)
      )
      (0x01000000:Object):Item = (
        (0x03000000:NameValue):b = 2 (INTEGER)
      )
    )
  • A multidimensional array; for example:
    "array3" : [ [1.1], [2.1] ]
    The following message tree is produced:
    (0x01001000:Array):array3 = (
      (0x01001000:Array):Item = (
        (0x03000000:NameValue):Item = 1.1E+0 (FLOAT)
      )
      (0x01001000:Array):Item = (
        (0x03000000:NameValue):Item = 2.1E+0 (FLOAT)
      )
    )

Example JSON message

The following example shows a simple JSON message:

{
    "name" : "John Doe",
    "age" : -1.0,
    "known" : false,
    "address" : { "street" : null,
                  "city" : "unknown" },
    "belongings" : ["item1", "item2", "item3"]
}

This JSON input produces the following integration node logical message tree:

(0x01000000:Object):JSON            = ( ['json' : 0xd55fc8]
  (0x01000000:Object):Data = (
    (0x03000000:NameValue):name       = 'John Doe' (CHARACTER)
    (0x03000000:NameValue):age        = -1E+0 (FLOAT)
    (0x03000000:NameValue):known      = FALSE (BOOLEAN)
    (0x01000000:Object   ):address    = (
      (0x03000000:NameValue):street = NULL
      (0x03000000:NameValue):city   = 'unknown' (CHARACTER)
    )
    (0x01001000:Array    ):belongings = (
      (0x03000000:NameValue):Item = 'item1' (CHARACTER)
      (0x03000000:NameValue):Item = 'item2' (CHARACTER)
      (0x03000000:NameValue):Item = 'item3' (CHARACTER)
    )
  )
)