{
"$id": "https://example.com/person.schema.json",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Person",
"type": "object",
"properties": {
"firstName": {
"type": "string",
"description": "The person's first name."
},
"lastName": {
"type": "string",
"description": "The person's last name."
},
"age": {
"description": "Age in years, which must be equal to or greater than zero.",
"type": "integer",
"minimum": 0
}
},
"required": ["firstName", "lastName"]
}
Reusing Types from a JSON Schema
JSON Schema is a standard that provides a format for the JSON data required for a given application and how to interact with it. Many existing data formats or types are expressed using this standard. In particular, REST APIs described by RAML files are likely to have their types defined in JSON schemas.
To reuse predefined types, you can load the JSON schema into DataWeave to make the types structure available for use in your scripts.
The JSON schema loader parses schemas using the JSON Schema Draft 7ˆ.
Import a Type from a JSON Schema
The following example shows a JSON schema (Person.json
) in the resources directory:
example/schema/Person.json
):The following example shows how to import the type using the JSON schema loader:
import * from jsonschema!example::schema::Person
Import Syntax
To import JSON schema types, use the following syntax, where:
-
typeToImport
: You can use*
alone to import all types defined in the schema or you can import a single type from the schema using, for example,Root
. You can also import JSON schema types with a different name, for example,Root as Person
, which enables you to reference the type with that name in the script. -
pathToJsonSchema
: To specify the path to the schema file, replace the file separators with::
and remove the.json
extension from the file name. For example, if the path to the schema isexample/schema/Person.json
, useexample::schema::Person
.
import _typesToImport_ from jsonschema!_pathToJsonSchema_
The following example shows how to import a type:
import * from jsonschema!example::schema::Person
Use Your Types in a DataWeave Script
Including the import directive from the above example in the script header loads all the existing types in the JSON schema. In import * from jsonschema!example::schema::Person
, the only existing type is the Root
type, specified at the root which describes an Object that can have three properties (firstName
, lastName
, and age
). This is equivalent to declaring the following type in your DataWeave script:
%dw 2.0
type Root = { firstName: String, lastName: String, age?: Number }
Notice that age
is the only optional field, as indicated by the ?
.
You can use the type to determine if a value follows the structure defined by the JSON schema.
The following example outputs the value true
because the object contains the required fields, firstName
and lastName
:
%dw 2.0
import * from jsonschema!jsonschema!example::schema::Person
---
{
firstName: "John",
lastName: "Doe"
} is Root
"true"
The following example outputs the value false
because the object doesn’t contain the required fields, firstName
and lastName
:
%dw 2.0
import * from jsonschema!jsonschema!example::schema::Person
---
{
firstName: "John",
age: 20
} is Root
"false"
Use Definitions inside Schemas
DataWave loads the definitions inside JSON schemas when the module is imported:
example/schema/Account.json
):{
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": {
"address": {
"type": "object",
"properties": {
"street_address": {
"type": "string"
},
"city": {
"type": "string"
},
"state": {
"type": "string"
}
},
"required": [
"street_address",
"city",
"state"
]
},
"person": {
"type": "object",
"properties": {
"firstName": {
"type": "string",
"description": "The person's first name."
},
"lastName": {
"type": "string",
"description": "The person's last name."
},
"age": {
"description": "Age in years, which must be equal to or greater than zero.",
"type": "integer",
"minimum": 0
}
},
"required": [
"firstName",
"lastName"
]
}
},
"type": "object",
"properties": {
"person": {
"$ref": "#/definitions/person"
},
"address": {
"$ref": "#/definitions/address"
}
}
}
You can import the types from that schema with the following directive:
import * from jsonschema!example::schema::Account
The types defined in the schema have the same effect as declaring the following types:
type Root = { address?: address, person?: person } type address = { street_address: String, city: String, state: String } type person = { firstName: String, lastName: String, age?: Number }
Use the import directive to import a single type from the schema:
import address from jsonschema!example::schema::Account
To avoid type-name collision, you can use the as
keyword to change the imported type name to another name:
import address as Account_Address from jsonschema!example::schema::Account
Facilitate Usage with Pattern Matching
You can use the types imported from the JSON schemas to take a specific action when an input is of a certain type. These imported types are useful for pattern matching.
The following example outputs the value person
because the object is importing that type definition:
%dw 2.0
import * from jsonschema!example::schema::Account
---
{
firstName: "John",
lastName: "Doe"
} match {
case is person -> "PERSON"
case is address -> "ADDRESS"
else -> "NO TYPE MATCHED"
}
"PERSON"
The following example outputs the value address
because the object is importing that type definition:
%dw 2.0
import * from jsonschema!example::schema::Account
---
{
street_address: "742 Evergreen Terrace",
city: "Gotham",
State: "OH"
} match {
case is person -> "PERSON"
case is address -> "ADDRESS"
else -> "NO TYPE MATCHED"
}
"ADDRESS"
Built-in JSON Schema Types
DataWeave supports the following JSON schema types transformed into DataWeave types:
JSON Schema Type | DataWeave Type |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Limitations
-
DataWeave doesn’t support formats on JSON schema string types and transforms these types to
String
without any validation or restriction. -
DataWeave doesn’t support restrictions on number types such as maximums or minimums and transforms these types to
Number
without any validation or restriction. -
DataWeave doesn’t support patterns.
Object types
DataWeave marks non-required properties in JSON Schema object types as optional properties in the DataWeave Object type.
The following example outputs a DataWeave type:
{
"type": "object",
"properties": {
"name": { "type": "string" },
"email": { "type": "string" },
"address": { "type": "string" },
"telephone": { "type": "string" }
},
"required": ["name", "email"]
}
%dw 2.0
type Root = { address?: String, name: String, telephone?: String, email: String }
If additional properties are allowed, DataWeave produces an open Object definition.
The following example outputs a DataWeave type:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"number": { "type": "number" },
"street_name": { "type": "string" },
"street_type": { "type": "string",
"enum": ["Street", "Avenue", "Boulevard"]
}
},
"required": ["number"],
"additionalProperties": true
}
%dw 2.0
type Root = { number: Number, street_type?: "Street" | "Avenue" | "Boulevard", street_name?: String }
If, on the contrary, additional properties aren’t allowed, DataWeave produces a closed Object definition.
The following example outputs a DataWeave type:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"number": { "type": "number" },
"street_name": { "type": "string" },
"street_type": { "type": "string",
"enum": ["Street", "Avenue", "Boulevard"]
}
},
"required": ["number"],
"additionalProperties": false
}
%dw 2.0
type Root = {| number: Number, street_type?: "Street" | "Avenue" | "Boulevard", street_name?: String |}
Built-in JSON Schema Support for Subschema Keywords
Using subschema keywords in JSON schema produces complex types based on the provided subschemas.
JSON Schema Keyword | DataWeave Type |
---|---|
|
|
|
|
|
|
The following example outputs a DataWeave type: .JSON schema:
{
"anyOf": [
{ "type": "string" },
{ "type": "number" }
]
}
%dw 2.0
type Root = (String | Number)