JSON Schema as input for Wizard
JSON Schema as input for Wizard
As an alternative to OWL, JSON Schema is increasingly popular. This section describes the currently supported features and limitations of our JSON Schema input, but be aware that our JSON Schema import effort is still under development. This section describes supported features, some of the limitations of the current implementation and examples that work with the current implementation.
Related documentation: Please find the documentation for wizard step 1, and the way to add a JSON Schema (Step 0) to the environment.
Supported JSON Schema constructs and features
We aim to support JSON Schema version Draft 07.
Semantic Treehouse is able to import the following example schema and offer sub-properties in the wizard that respect the cardinality constraints and the value constraints that are mentioned in the JSON Schema.
We support, as far as we know, all datatypes. We provide basic support for advanced constructs: OneOf, AnyOf and AllOf. For OneOf lists, we don't offer all of the options but only an arbitrary first schema of a possibly nested OneOf list. AllOf schema lists will all be checked for possible sub-properties and offered in the Wizard.
General piece of advise: Be aware that the Wizard has a snapshotting principle, so any changes to the underlying schema will not be pushed to any already added elements in the message model. You'd need to remove the Elements and re-add them in order to see the changes you made to the JSON Schema.
Main limitations
About reference resolution
As with other schema languages, JSON Schema allows references to other types, so you don't have to repeat yourself in the schema. A nice example is a Postal Address Type that describes the sub-properties of a postal address. If this postal address occurs five times in different places of the schema it is nice to not have to copy paste these sub-schemas. JSON Schema offers the reference field $ref
that can hold a reference to a sub-schema, to solve this problem.
Our implementation does support $ref
links to the definitions in the entered schema (local $ref
links, eg.: "$ref": "#/definitions/PostalAddressType"
).
Furthermore if the entire schema is publicly available then you can use our JSON Schema Preprocessor to load the entire schema by giving the URL.
However our implementation does not support resolving remote references ("$ref": "https://somedomain.org/schemas/core.json#PostalAddressType"
) that are pasted into the Local Content field of a JSON Schema Specification Version. Read more about how to enter JSON Schemas here..
Applicator Keywords Construct
JSON Schema offers support for conditional application of multiple sub-schemas, through what is called an Applicator vocabulary. For example, consider a property called sensorLocation
then the range (or target) of that property may be either one of the following objects, a GPS coordinate, or a visiting address. The target schema can be modeled then as a OneOf
construct, where any target value of the property sensorLocation has to comply to exactly one of the sub-schemas, and not to both.
In the current implementation:
- Only one of the sub-schemas under a
OneOf
list is shown to the user.
Reverse properties
JSON Schemas have an innate direction or tree-form: there is always a root object that can hold child objects, and so on. Even though conceptually, it can be argued for any property that the reverse property is also valid and relevant to modelers. As an example, consider a Person
schema that holds property drives
with the target schema of an object Car
. It can be equally validly modeled as a Car
schema that holds a property drivenBy
with target schema Person
. Ideally, the wizard would offer the "reverse" property of drivenBy to a modeler who makes a message model of a Car. The current implementation does not offer support for showing this reverse property, though it has to be noted that JSON Schemas don't hold reverse text for properties (like in this example the name drivenBy
).
- No Reverse properties are being offered yet (the property Person drives Car has a reverse of Car is driven by Person). Currently the wizard only offers properties in the direction of 'down the tree'.
Multiple types for a schema
Multiple types for a schema are not supported, though they are valid in JSON Schemas. A schema is either of type object or of type boolean for example, but both of them
Example 1: A very simple product schema
The following schema provides a simple schema that Semantic Treehouse can import. It describes a product through its ID and its name.
To follow this example we need to create two things:
- a JSON schema specification, with a version that has the schema in its content. This provides the basis from which message models can be derived.
- a new message model specification, with a version. This instantiates a new message model that can be based on the JSON schema specification version (and offers editing and new code generation options).
The JSON schema content can be pasted into the local content field of a new JSON schema specification version. The JSON pointer field points to the root of the schema by default (using the character '#' to indicate the root of the document). In this case, we wish to start the wizard at the root, so the default value is fine.
{
"$schema": "https://json-schema.org/draft-07/schema",
"$id": "https://example.com/product-0.schema.json",
"title": "Product",
"description": "A product offering and its characteristics.",
"type": "object",
"properties": {
"productId": {
"description": "The unique identifier for a product",
"type": "integer"
},
"productName": {
"description": "The name for the product",
"type": "string"
}
},
"required": ["productId"]
}
After loading the wizard (reachable through 'Create new message model' or through the 'Edit Message model version' screen), the wizard should now show two possible sub-properties productId [1..1] and productName[0..1], meaning a mandatory field productId, and an optional field called productName.
These can be added in our derived message model, by clicking the plus-signs. As an exercise in message model editing, you can edit the name of the sub-element productId
to productNumber
or try to make the productName
field required. Note that editing the message model elements does not change the original json schema. The wizard only creates a snapshot of the information frfom the schema when you add an element, and the wizard never feeds back any changes into the source json schema.
Example 2: A more detailed product schema
The following schema features sub-properties beyond the first level and array types, with some constraints.
{
"$schema": "https://json-schema.org/draft-07/schema",
"$id": "https://example.com/product-3.schema.json",
"title": "Product",
"description": "Arrays with min and maxItems and arrays of objects.",
"type": "object",
"properties": {
"productId": {
"description": "The unique identifier for a product",
"type": "integer"
},
"productName": {
"description": "The name for the product.",
"type": "string"
},
"productTags": {
"description": "Search tags that characterize the product.",
"type": "array",
"minItems": 8,
"maxItems": 10,
"items": {
"type": "string"
}
},
"previousProducts": {
"description": "Previous products .",
"type": "array",
"minItems": 4,
"maxItems": 10,
"items": {
"type": "object",
"properties": {
"oldProductId": {
"type": "string"
}
}
}
}
},
"required": ["productId", "previousProductIds"]
}
Example 3: Using AllOf constraint
The final example shows how several schemas listed in an allOf
constraint of the root are all picked up by the Wizard to offer the message model designer these properties as options for inclusion in the new message model.
{
"$id": "https://www.semantic-treehouse.nl/fit/jsonschema/testset/5.json",
"$schema": "https://json-schema.org/draft-07/schema",
"title": "Product Details: ID, old IDs and Name lookup. Uses allOf and own props.",
"type": "object",
"allOf": [
{
"properties": {
"id": {
"type": "string",
"format": "uri"
}
}
},
{
"properties": {
"oldIds": {
"type": "array",
"items": {
"type": "string",
"format": "uri"
}
}
}
}
],
"properties": {
"name": {
"type": "string"
}
}
}
Readers are cordially invited to experiment with the wizard and generate message models from them. In return we would like to ask for feedback of your usage and any findings with your own schemas, since there are many flavors to schema design.