Contact Free trial Login

Validating Documents Against a JSON Schema with the JSON Module

The <json:validate-schema> operation validates that the input content is compliant with a given JSON schema.

<flow name="process">
    <json:validate-schema schema="/schema/my-schema.json" />
</flow>

By default, this operation looks for the input document at the message payload level. However, you can supply your own input, for example:

<flow name="process">
    <file:read path="document.json" target="jsonDoc" />
    <json:validate-schema schema="/schema/my-schema.json">
        <json:content>#[vars.jsonDoc]</json:content>
    </json:module:validate-schema>
</flow>

Note that you can use the <json:validate-schema> component inside a <validation:all> element.

Handling a Validation Error

If the validation is successful, nothing happens, and the flow continues to the next operation. If it fails, an JSON:SCHEMA_NOT_HONOURED error is raised.

The JSON:SCHEMA_NOT_HONOURED error is a complex one. Because the validation can fail for any number of reasons, the error contains a JSON array of objects. Each of those objects contains information on each of the found errors.

For example, consider the following input JSON:

Invalid JSON
[
  {"a": "", "b": ""},
  {"a": "", "b": ""},
  {"a":""},
  {"a": "", "b":""},
  {"b": ""}
]

Also consider the following JSON Schema:

JSON Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "a": {
        "type": "string",
		"minLength": 1,
		"maxLength": 255
		},
      "b": {
        "type": "string",
		"minLength": 1,
		"maxLength": 255
      }
    },
    "required": ["a", "b"]
  }
}

As you can see, the input JSON is invalid because both a and b String attributes are required, and they both need to be of at least one character long.

So, if your use case is to perform the validation, and if it fails, to append the report to a file, you can do this:

<flow name="validate">
    <try>
        <json:validate-schema schema="/schema/object-array-schema.json" />
        <error-handler>
            <on-error-propagate type="JSON:SCHEMA_NOT_HONOURED">
                <file:write config-ref="file" path="errors/jsonSchemas.json" mode="APPEND">
                    <file:content>#[error.errorMessage.payload]</file:content>
                </file:write>
            </on-error-propagate>
        </error-handler>
    </try>
</flow>

The text added to the file would be something like this:

[ {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/schema/object-array-schema.json#",
    "pointer" : "/items/properties/a"
  },
  "instance" : {
    "pointer" : "/0/a"
  },
  "domain" : "validation",
  "keyword" : "minLength",
  "message" : "string \"\" is too short (length: 0, required minimum: 1)",
  "value" : "",
  "found" : 0,
  "minLength" : 1
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/schema/object-array-schema.json#",
    "pointer" : "/items/properties/b"
  },
  "instance" : {
    "pointer" : "/0/b"
  },
  "domain" : "validation",
  "keyword" : "minLength",
  "message" : "string \"\" is too short (length: 0, required minimum: 1)",
  "value" : "",
  "found" : 0,
  "minLength" : 1
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/schema/object-array-schema.json#",
    "pointer" : "/items/properties/a"
  },
  "instance" : {
    "pointer" : "/1/a"
  },
  "domain" : "validation",
  "keyword" : "minLength",
  "message" : "string \"\" is too short (length: 0, required minimum: 1)",
  "value" : "",
  "found" : 0,
  "minLength" : 1
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/schema/object-array-schema.json#",
    "pointer" : "/items/properties/b"
  },
  "instance" : {
    "pointer" : "/1/b"
  },
  "domain" : "validation",
  "keyword" : "minLength",
  "message" : "string \"\" is too short (length: 0, required minimum: 1)",
  "value" : "",
  "found" : 0,
  "minLength" : 1
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/schema/object-array-schema.json#",
    "pointer" : "/items"
  },
  "instance" : {
    "pointer" : "/2"
  },
  "domain" : "validation",
  "keyword" : "required",
  "message" : "object has missing required properties ([\"b\"])",
  "required" : [ "a", "b" ],
  "missing" : [ "b" ]
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/schema/object-array-schema.json#",
    "pointer" : "/items/properties/a"
  },
  "instance" : {
    "pointer" : "/2/a"
  },
  "domain" : "validation",
  "keyword" : "minLength",
  "message" : "string \"\" is too short (length: 0, required minimum: 1)",
  "value" : "",
  "found" : 0,
  "minLength" : 1
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/schema/object-array-schema.json#",
    "pointer" : "/items/properties/a"
  },
  "instance" : {
    "pointer" : "/3/a"
  },
  "domain" : "validation",
  "keyword" : "minLength",
  "message" : "string \"\" is too short (length: 0, required minimum: 1)",
  "value" : "",
  "found" : 0,
  "minLength" : 1
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/schema/object-array-schema.json#",
    "pointer" : "/items/properties/b"
  },
  "instance" : {
    "pointer" : "/3/b"
  },
  "domain" : "validation",
  "keyword" : "minLength",
  "message" : "string \"\" is too short (length: 0, required minimum: 1)",
  "value" : "",
  "found" : 0,
  "minLength" : 1
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/schema/object-array-schema.json#",
    "pointer" : "/items"
  },
  "instance" : {
    "pointer" : "/4"
  },
  "domain" : "validation",
  "keyword" : "required",
  "message" : "object has missing required properties ([\"a\"])",
  "required" : [ "a", "b" ],
  "missing" : [ "a" ]
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "file:/schema/object-array-schema.json#",
    "pointer" : "/items/properties/b"
  },
  "instance" : {
    "pointer" : "/4/b"
  },
  "domain" : "validation",
  "keyword" : "minLength",
  "message" : "string \"\" is too short (length: 0, required minimum: 1)",
  "value" : "",
  "found" : 0,
  "minLength" : 1
} ]

Schema Redirections

Some JSON schemas might reference other schemas through a public URI. However, you might not want to fetch those schemas from the internet, mainly for performance and security reasons.

The solution to that problem is to include all the main and referenced schemas in your application. However, this solution generates a new problem: You need to make the original schema point to your local schemas instead of the public ones.

To help with this problem, the module has the concept of schema redirects, which lets you replace an external reference with a local one, without the need to modify the schema itself:

<flow name="process">
    <json:validate-schema schema="/schema/my-schema.json">
        <json:schema-redirects>
            <json:schema-redirect from="http://mule.org/schemas/fstab.json" to="schema/fstab.json"/>
        </json:schema-redirects>
    </json:validate-schema>
</flow>

The example above redirects the schema at http://mule.org/schemas/fstab.json with one shipped inside your application with the path schema/fstab.json

Additional Options

The validator contains additional options, such as whether to allow duplicate keys or not, how to treat dereferencing, and so on.

For complete details, see JSON Module Documentation Reference.

See Also

Was this article helpful?

💙 Thanks for your feedback!

Edit on GitHub