Serializer options

Options of the json.Serializer class for controlling serialization behavior.

Table 1. Serializer options
Option Description Affects Default Example use
allowImplicitConversion This option modifies the behavior of JSON deserialization by allowing implicit type conversions when the JSON property specifies one type, but the values suggest another.
Typically, json.serializer implements strict schema validation during deserialization. If a JSON property is expected to be a certain type (for example, boolean), but the provided values are of a different type (for example strings), a deserialization error should occur.
  • Primitive Types: are not affected by allowImplicitConversion since Genero BDL allows implicit conversion for these types.
  • Arrays: When allowImplicitConversion is enabled, an array of INTEGER/NUMBER(DECIMAL), BOOLEAN, or STRING can accept values that are implicit conversions for those types, provided the values are valid for the intended type, even if represented incorrectly. For example, a boolean value is accepted with values represented as follows: 1, 0, true, false, "true", "false", or "1", "0". Note that allowImplicitConversion acts on the elements of a dictionary like an array.
  • Records/Objects: Currently, records or objects are not affected by the allowImplicitConversion option.
Important:

The option does not apply to simple-type oneOf JSON schemas because allowing implicit type conversion would compromise the integrity of schema validation, potentially leading to ambiguous or incorrect matches.

Deserialization (JSON to BDL) False

(implicit conversion is not allowed)

CALL json.Serializer.setOption("allowImplicitConversion",1). For an example, go to JSON to BDL deserialization option to allow implicit conversions
allowNullAsDefault Allow NULL values to be accepted during deserialization when the json_null="null" attribute is not explicitly specified. Deserialization (JSON to BDL) False

(NULL values are not allowed)

CALL json.Serializer.setOption("allowNullAsDefault",1). For examples, go to JSON to BDL deserialization options to allow nulls
serializeNullAsDefault Allow NULL values to be accepted during serialization, even if constraints are set (for example, JSONRequired defined or json_null="null" not defined). Serialization (BDL to JSON) False

(NULL values are not allowed)

CALL json.Serializer.setOption("serializeNullAsDefault",1). For examples, go to BDL to JSON serialization options to allow nulls
json_null="null" Attribute required to deserialize JSON null values ​​into BDL variables, or to enable serialization (BDL to JSON) of null values. Both Serialization (BDL to JSON) and Deserialization (JSON to BDL) Not set For more information about managing null with the json_null attribute, go to NULLs and empty structures.

Examples

Options of the json.Serializer class usage examples.

JSON to BDL deserialization options to allow nulls

To relax deserialization, you can set the allowNullAsDefault option to allow nulls.

By default, Genero Web Services JSON to Genero BDL deserialization will raise errors if the JSON content does not match the BDL variable receiving the data. For example, you have a Genero BDL record defined as follows:
TYPE tAddress RECORD
    street STRING,
    city STRING,
    state STRING,
    zip STRING
END RECORD

TYPE tCustomer RECORD
    id STRING,
    name STRING,
    address tAddress
END RECORD
The following JSON document will by default raise conversion errors because the "address" element is defined as "null", which does not correspond with the BDL variable:
{
  "id": "1",
  "name": "John Doe",
  "address": null
}
To avoid the conversion error, set the following option to allow nulls in your server module:
CALL json.Serializer.setOption( "allowNullAsDefault", 1 )

For more details, go to json.Serializer.setOption.

Alternatively, it is recommended that you define BDL variables with the attributes value json_null="null" to handle JSON serialization of null values.
TYPE tAddress RECORD ATTRIBUTES(json_null="null")
    street STRING,
    city STRING,
    state STRING,
    zip STRING
END RECORD
For more information, go to Using the json_null="null" attribute.

BDL to JSON serialization options to allow nulls

To relax serialization, you can set the serializeNullAsDefault option to allow nulls.

By default, Genero Web Services BDL to JSON serialization will raise errors if NULL values are sent.

Null values can be allowed in Genero BDL in two ways:

In this example, the str variable is not set with a value and is therefore NULL when passed in the call to json.Serializer.variableToJSON(str, writer) and an error is raised.
IMPORT JSON

CONSTANT TNAME = "one_value_withoutNull()"
DEFINE 
    writer json.JSONWriter,
    t TEXT,
    str STRING

MAIN
    LOCATE t in MEMORY
    DISPLAY "\nSTART ", TNAME

    TRY
        LET writer = json.JSONWriter.Create()
        CALL writer.setOutputCharset("UTF-8")
        CALL writer.writeToText(t)
        CALL writer.startJSON()
        CALL json.Serializer.variableToJSON(str, writer)
        CALL writer.endJSON()
        CALL writer.close()
        DISPLAY "Should raise a serialization error"
        DISPLAY "json: ", t
        EXIT PROGRAM 1
    CATCH
        DISPLAY status || ": " || sqlca.sqlerrm
        DISPLAY "END " || TNAME || " ok"
    END TRY
END MAIN
error-15807 is raised and the following output is returned because "str" is NULL:
START one_value_withoutNull()
-15807: Primitive value cannot be serialized to 'null'
END one_value_withoutNull() ok
To avoid serialization errors, call json.Serializer.setOption("serializeNullAsDefault", 1) to allow null values, even when a JSONRequired constraint is set on the record. This is demonstrated in the following example. Note that you must reset the serializeNullAsDefault option to its default setting at the end of the program.
IMPORT JSON

CONSTANT TNAME = "object_withOption()"

DEFINE rec RECORD
    a STRING ATTRIBUTE(JSONRequired),
    b INTEGER
END RECORD
DEFINE 
    writer json.JSONWriter,
    t TEXT
MAIN
    LOCATE t in MEMORY
    DISPLAY "\nSTART ", TNAME

    TRY
        LET writer = json.JSONWriter.Create()
        CALL writer.setOutputCharset("UTF-8")
        CALL writer.writeToText(t)
        CALL writer.startJSON()
        CALL json.Serializer.setOption("serializeNullAsDefault",1)
        CALL json.Serializer.variableToJSON(rec, writer)
        CALL writer.endJSON()
        CALL writer.close()
        DISPLAY "json: ", t
    CATCH
        DISPLAY status || ": " || sqlca.sqlerrm
        EXIT PROGRAM 1
    END TRY

    DISPLAY "END " || TNAME || " ok"

    # reset serializeNullAsDefault to default
    CALL json.Serializer.setOption("serializeNullAsDefault",0)

END MAIN

No serialization error is raised and the following output is produced with null values:

START object_withOption()
json: {"a":null,"b":0}
END object_withOption() ok

For more details about serializeNullAsDefault, go to json.Serializer.setOption.

Serialization error with nulls in an array

By default, Genero Web Services BDL to JSON serialization will raise errors if NULL values are sent in an array as in this example:
IMPORT JSON

CONSTANT TNAME = "array_withoutNull()"
DEFINE arr DYNAMIC ARRAY OF STRING
DEFINE 
    writer json.JSONWriter,
    t TEXT

MAIN
    LOCATE t in MEMORY
    DISPLAY "\nSTART ", TNAME

    LET arr[1] = "foo"
    LET arr[2] = NULL

    TRY
        LET writer = json.JSONWriter.Create()
        CALL writer.setOutputCharset("UTF-8")
        CALL writer.writeToText(t)
        CALL writer.startJSON()
        CALL json.Serializer.variableToJSON(arr, writer)
        CALL writer.endJSON()
        CALL writer.close()
        DISPLAY "Should generate serialization error"
        DISPLAY "json: ", t
        EXIT PROGRAM 1
    CATCH
        DISPLAY status || ": " || sqlca.sqlerrm
        DISPLAY "END " || TNAME || " ok"
    END TRY
END MAIN
error-15807 is raised and the following output is returned because "arr[2]" is NULL:
START array_withoutNull()
-15807: Array cannot serialize 'null' elements. It requires json_null="null"
END array_withoutNull() ok
To prevent serialization errors in arrays, you should call json.Serializer.setOption("serializeNullAsDefault", 1) before writing to the array. This will allow null values. Note that you must reset the serializeNullAsDefault option to its default setting at the end of the program.
IMPORT JSON

CONSTANT TNAME = "array_withOption()"
DEFINE arr DYNAMIC ARRAY OF STRING
DEFINE 
    writer json.JSONWriter,
    t TEXT

MAIN
    LOCATE t in MEMORY
    DISPLAY "\nSTART ", TNAME

    LET arr[1] = "foo"
    LET arr[2] = NULL

    TRY
        LET writer = json.JSONWriter.Create()
        CALL writer.setOutputCharset("UTF-8")
        CALL writer.writeToText(t)
        CALL writer.startJSON()
        CALL json.Serializer.setOption("serializeNullAsDefault",1)
        CALL json.Serializer.variableToJSON(arr, writer)
        CALL writer.endJSON()
        CALL writer.close()
        DISPLAY "json: ", t
    CATCH
        DISPLAY status || ": " || sqlca.sqlerrm
        EXIT PROGRAM 1
    END TRY

    DISPLAY "END " || TNAME || " ok"
    # reset serializeNullAsDefault to default
    CALL json.Serializer.setOption("serializeNullAsDefault",0)
END MAIN

No serialization error is raised and the following output is produced with null values:

START array_withOption()
json: ["foo",null]
END array_withOption() ok

For more details about serializeNullAsDefault, go to json.Serializer.setOption.

Using json_null="null" to manage JSON serialization of null values

Alternatively, it is recommended that you define BDL variables with the attributes value json_null="null" to allow JSON serialization of null values.
DEFINE str STRING ATTRIBUTE(json_null="null")
You can define an array with the json_null="null" attribute to handle a null index or an attempt to serialize it without elements. For examples, go to Using the json_null="null" attribute.

JSON to BDL deserialization option to allow implicit conversions

To relax deserialization, you can set the allowImplicitConversion option to allow implicit data conversion.

By default, Genero Web Services deserialization will raise errors if the JSON content does not match the BDL variable receiving the data. For more information on implicit and explicit conversion of JSON to Genero BDL, go to Understanding implicit/explicit serialization.

In this example, you have a BDL variable that is defined as follows:
PRIVATE TYPE TypedLists RECORD
    ints DYNAMIC ARRAY OF INT,
    strings DYNAMIC ARRAY OF STRING
END RECORD
The following JSON document will raise conversion errors by default because the "strings" array does not contain valid string values. For example, it should be formatted as "strings": ["1", "2"]" to correspond with the expected data type. Here is the original JSON:
{
    "ints": [1, 2],
    "strings": [1, 2]
}
To avoid the conversion error, you can set the following option in your server module to allow implicit type conversion:
CALL json.Serializer.setOption( "allowImplicitConversion", 1 )

For more details, go to json.Serializer.setOption.