Complex type serialization

This section focuses on implicit/explicit conversion comparisons for JSON deserialization of arrays between json.Serializer and util.json. It covers the rules for type casting, and failure scenarios, and highlights the impact of setting the allowImplicitConversion option.

Important: Type checking array/dictionary types
When using json.Serializer, type checking is strictly enforced only for the following structures:
  • STATIC ARRAY
  • DYNAMIC ARRAY
  • DICTIONARY
JSON objects in Genero BDL can be generated in three ways:
  1. RECORD: a statically typed structure; each member is typed and must conform to primitive type conversion rules.
  2. DICTIONARY: a dynamic object with string keys; each value must conform to conversion rules similar to array elements. (For details, go to Table 2)
  3. util.JSONObject: a dynamic, open object; no strict type enforcement is applied during serialization or deserialization.

In the tables below, the term FGL-Object refers to 4GL structured types such as RECORD and DICTIONARY. These types are schema-aware and their members are subject to strict validation when using json.Serializer. FGL-Object does not include util.JSONObject, which behaves as an open container with no enforced type structure.

The following tables compare these different data types along with their structures, typing, conversion rules, and best use cases. Refer to Detailed Compatibility Matrix for JSON Arrays for a detailed comparisons between util.json and json.Serializer.
Table 1. Conversion of Genero BDL types to JSON: Characteristics and Best Practices
Type Structure Typing Conversion rules Best use case
RECORD Fixed fields Strong typing Strict (per field) Known schema, validated structures
DICTIONARY Dynamic fields Dynamic, typed values Like ARRAY (see Table 2) JSON with dynamic or unknown keys
util.JSONObject Fully dynamic No enforced typing None Raw JSON, flexible usage

JSON arrays can be generated in Genero BDL in two ways:

  1. FGL-Array (DYNAMIC or STATIC ARRAY):

    This is a typed array structure where each element must conform to strict conversion rules based on the array's declared base type (for example, DYNAMIC ARRAY OF INTEGER, DYNAMIC ARRAY OF RECORD). Type mismatches lead to deserialization errors.

    The term FGL-Array refers to both DYNAMIC ARRAY OF element-type and ARRAY[n] OF element-type.

  2. util.JSONArray:

    util.JSONArray is a dynamic, open array. No strict type enforcement is applied during serialization or deserialization; elements of any type (primitive or complex) can coexist.

On the other hand, the elements of a dynamic array must comply with the conversion rules described in Table 2.

Table 2. JSON array element compatibility matrix (json.Serializer behavior)
Target type JSON token type accepted (default) With allowImplicitConversion = true
BOOLEAN true, false, 0, 1 "true", "false", "0", "1"
FGL-INTEGER integer string representing integer
FGL-NUMBER number string representing integer/float
FGL-STRING string number, boolean
DATE string (ISO 8601) -
DATETIME string -
FGL-ARRAY util.JSONArray array -
FGL-OBJECT util.JSONObject object -
with attribute json_null="null" null -
Table 3. Detailed compatibility matrix for JSON arrays
Target type Accepted JSON inputs json.Serializer util.json Notes
BOOLEAN
true, false OK OK Direct mapping
1, 0, "true", "false", "1", "0" ERROR (unless allowImplicitConversion is used) OK Implicit cast: JSON-String/Number to FGL-BOOLEAN
"toto" ERROR OK

silent cast to NULL

FGL-INTEGER
123 OK OK Direct mapping
"123" ERROR (unless allowImplicitConversion is used) OK JSON-String to FGL-INTEGER
"abc" ERROR OK

silent cast to NULL

FGL-NUMBER 123.45, "123.45" OK OK Same behavior as FGL-INTEGER
FGL-STRING "foo" OK OK
DATE
"YYYY-MM-DD", timestamp OK OK JSON-String must match format or be numeric
"not-a-date" ERROR OK

silent cast to NULL

FGL-Object

util.JSONObject

{...} OK OK

FGL-ARRAY

util.JSONArray

[valid_elements] OK OK Recursively deserialized
[] OK OK Accepted even if empty
[invalid_element] ERROR OK util.JSON: Invalid when assigning a primitive to a complex type, or vice versa.
with attribute json_null="null" null ERROR OK json.Serializer: NULL handling configurable