JSONAllOf
Combine multiple record schemas into a single type using the JSONAllOf attribute in Genero BDL.
Syntax
JSONAllOf is an optional attribute that allows you to combine multiple record types into a single schema, following the JSON Schema allOf keyword.
This serializer-specific attribute is supported only by json.Serializer and does not work with util.JSON.
Usage
The JSONAllOf attribute enables you to define a type that merges the properties of several record types. This is useful for composing complex types from reusable components. The resulting type will include all unique properties from the specified record types.
There is a new fglrestful option that enables you to preserve the integrity of
allof schemas. By using the --no-merge-allof option, you can
disable the merging of properties in schemas where the JSONAllOf attribute is
applied.
BDL Example
This sample illustrates how to apply the JSONAllOf and
JSONRequired attributes to define composite and mandatory properties in JSON
schemas.
IMPORT com
DEFINE g_nextId INTEGER = 1
DEFINE Employees DYNAMIC ARRAY OF Employee
TYPE Address RECORD
street STRING,
city STRING ATTRIBUTE(JSONRequired)
END RECORD
TYPE Person RECORD
id INTEGER,
name STRING ATTRIBUTE(JSONRequired),
age INTEGER
END RECORD
TYPE Employee RECORD ATTRIBUTE(JSONAllOf)
employeeInfo Person,
employeeLocation Address
END RECORD
FUNCTION getEmployee(
id INTEGER ATTRIBUTE(WSParam))
ATTRIBUTE(WSGet, WSPath = "/getEmployee/{id}")
RETURNS(Employee)
DEFINE emp Employee
DEFINE ind INTEGER
DEFINE foundId BOOLEAN
IF Employees.getLength() = 0 THEN
LET Employees[1].employeeInfo.id = 1
LET Employees[1].employeeInfo.name = "Alice"
LET Employees[1].employeeInfo.age = 30
LET Employees[1].employeeLocation.street = "Rue Montesquieu"
LET Employees[1].employeeLocation.city = "Paris"
END IF
FOR ind = 1 TO Employees.getLength()
IF Employees[ind].employeeInfo.id = id THEN
LET emp = Employees[ind]
LET foundId = TRUE
EXIT FOR
END IF
END FOR
IF NOT foundId THEN
CALL com.WebServiceEngine.SetRestError(404, "Employee not found")
END IF
RETURN emp
END FUNCTION
FUNCTION addEmployee(
empIn Employee)
ATTRIBUTE(WSPost, WSPath = "/addEmployee", WSRetCode = '2XX')
RETURNS(Employee)
DEFINE empOut Employee
# Generate a dummy ID
LET g_nextId = g_nextId + 1
LET empIn.employeeInfo.id = g_nextId
LET Employees[Employees.getLength() + 1] = empIn
DISPLAY "getlength: ", Employees.getLength()
# Log server
DISPLAY SFMT("Adding employee '%1' with id: %2",
Employees[Employees.getLength()].employeeInfo.name,
Employees[Employees.getLength()].employeeInfo.id)
CALL com.WebServiceEngine.SetRestStatus(201)
LET empOut = empIn
RETURN empOut
END FUNCTION
Where:
- The
JSONAllOfattribute is set on the EmployeeTYPEdefinition. Note: this attribute can only be applied toTYPEdefinitions. - Two separate records, Person and Address, are defined and
combined into Employee at runtime. Each record has unique field names, ensuring
compatibility with JSON Schema
allOfsemantics. JSONRequiredis used withnameinPersonandcityinAddressto enforce these mandatory fields.
Compilation and validation rules
-
Restriction to TYPE definitions:
JSONAllOfcan only be used inTYPEdefinitions. -
Mutual exclusion:
JSONAllOfcannot be used withJSONOneOforJSONAdditionalPropertieson the same type. UsingJSONAllOfwithJSONOneOforJSONAdditionalPropertieswill result in error-9150 -
Restriction to RECORD types: Only
RECORDtypes are allowed as subschemas. UsingJSONAllOfwith unsupported types or functions will result in error-9153 -
Unique property names: All property names in the combined records must be unique. Using
JSONAllOfwith duplicate properties will result in error-9154 -
No nested JSONAllOf: Nesting
JSONAllOfattributes within anotherJSONAllOfstructure is not permitted, as it can create ambiguity and will result in error-9155.