Mapping to JSON

Rules for the construction of JSON payloads matching an Aspect model

payloads diagram

For understanding the construction rules, we define the following terms:

  • A Property’s leaf Characteristic means the Property’s Characteristic if it is not a Constraint, otherwise it means transitively following the Constraint’s bamm-c:baseCharacteristic until the value is not a Constraint any more.

  • A Property’s effective data type means the Property’s leaf Characteristic’s bamm:dataType.

  • A data type is scalar, if it is one of the allowed data types, but not a bamm:Entity.

In order to create JSON payloads that correspond to an Aspect model, the following rules are applied. The other way round they can also be used to describe a validation algorithm.

  • An Aspect model is always serialized as an unnamed JSON object.

  • For each Property:

    • If it is marked as optional, it may or may not be included in the payload. If, and only if, the Property is marked as optional and is included in the payload, then its value may be null, which is equivalent to it not being included in the payload.

    • If the Property’s effective data type is scalar with any date type other than rdf:langString, the Property is serialized as ${propertyName}: ${value} where ${value} is the JSON serialization of the respective Property’s value, details on mapping of the data types are given in Data type mappings. The value must adhere to the value range defined by the Property’s effective data type and possible Constraints on the Property’s Characteristic.

    • If the Property’s effective data type is scalar with the data type rdf:langString, the Property is serialized as a named JSON object (with ${propertyName} being the name of the JSON property), with keys for each available language tag of the Property and the corresponding localized string as the value.

    • If the Property’s effective data type is not scalar, it is serialized as a named JSON object (with ${propertyName} being the name of the JSON property), recursively using the same rules.

    • If the Property’s effective data type is an Entity which extends another Entity, it is serialized as a named JSON object (with ${propertyName} being the name of the JSON property). The Properties included for the Entity, are the Properties from the Entity itself as well as all Properties from the extended Entities, i.e. all Properties from ?thisEntity bamm:extends* [].

    • If the Property’s leaf Characteristic is a Collection, List, Set or Sorted Set, it is serialized as a named JSON array (with ${propertyName} being the name of the JSON array property).

  • Characteristics defined in the Aspect model other than the ones mentioned above are not subject to serialization.

  • Operations defined in the Aspect model are not subject to serialization.

  • Events defined in the Aspect model are not subject to serialization.

Data type mappings

A rich type tree is used in an Aspect model. As JSON offers only a very limited set of data types for primitive type values there are less options on how to represent the data. The mappings are described in the following table.

Aspect model data type

Corresponding JSON data type

Core Types

xsd:string

String

xsd:boolean

Boolean

xsd:decimal

Number

xsd:integer

Number

IEEE-floating-point numbers

xsd:double

Number

xsd:float

Number

Time and date

xsd:date

String

xsd:time

String

xsd:dateTime

String

xsd:dateTimeStamp

String

Recurring and partial dates

xsd:gYear

String

xsd:gMonth

String

xsd:gDay

String

xsd:gYearMonth

String

xsd:gMonthDay

String

xsd:duration

String

xsd:yearMonthDuration

String

xsd:dayTimeDuration

String

Limited-range integer numbers

xsd:byte

Number

xsd:short

Number

xsd:int

Number

xsd:long

Number

xsd:unsignedByte

Number

xsd:unsignedShort

Number

xsd:unsignedInt

Number

xsd:unsignedLong

Number

xsd:positiveInteger

Number

xsd:nonNegativeInteger

Number

xsd:negativeInteger

Number

xsd:nonPositiveInteger

Number

Encoded binary data

xsd:hexBinary

String

xsd:base64Binary

String

Miscellaneous types

xsd:anyURI

String

bamm:curie

String

rdf:langString

A JSON object with a structure as described in the rules above.

For example, a Property errorMessage with effective data type rdf:langString and the value "Could not load data"@en would be serialized in the JSON payload as follows:

{
  "errorMessage": {
    "en": "Could not load data"
  }
}

A Property errorMessages with a Collection Characteristic and effective data type rdf:langString could yield the payload:

{
  "errorMessages": [
    { "en": "Could not load data" },
    { "de": "Konnte Daten nicht laden" }
  ]
}
Due to the limits in the represention of numbers in JSON, the maximum integer number that can be used without losing precision is 2⁵³-1 (defined as Number.MAX_SAFE_INTEGER). This means that even if the Aspect model data type would allow higher or lower values, if they can not be represented in JSON, they can not be used. Affected data types are the unbounded numeric types xsd:decimal, xsd:integer, xsd:positiveInteger, xsd:nonNegativeInteger, xsd:negativeInteger, xsd:nonPositiveInteger and the bounded type xsd:unsignedLong. The other numeric types are not affected.