JSON Schema Validation in Mule: get failing field - json

I am using APIkit in Mule with RAML 0.8 and a JSON schema, as follows (example):
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"cart": {
"title": "",
"description": "",
"type": "object",
"properties": {
"internalNumber": {
"type": "integer"
}
},
"required": [
"internalNumber"
]
}
},
"required": [
"cart"
]
}
and in the Mule Flow, I catch the exception and show the following result:
#[exception.cause.message]
When a validation error occurs, I want to get the name of the field in which the validation failed. Instead, this is what I got:
Input
{
"cart": {
"internalNumber": "I must be an integer"
}
}
Output
"instance type (string) does not match any allowed primitive type (allowed: ["integer"])"
Expected output
{
"field": "cart.internalNumber",
"error": "instance type (string) does not match any allowed primitive type (allowed: ["integer"])"
}
All I want to know is if there is a way to get the name of the field in which the validation errors occurs.
Regarding the Mule Documentation, I can get the whole JSON string but not the name of the failing field...
I hope someone can give me a better solution.
Thanks!

Within your JSON Schema, add "required":"true" attribute, to make the fields mandatory.
You can also use JSON schema validator, in your mule flow, by referring to the updated schema.
Any of the case should through you an error with missing field.
Use below expression to get expected error message.
{
"errorMessage": "#[exception].toString().replace("\"","\\\"")"
}

Not sure if you are expecting it as an output or looking for a way to validate your input and schema.
I can try to suggest on "All I want to know is if there is a way to get the name of the field in wich the validation errors occurs."; to do this better validate your JSON and input data through online validator before defining definitions. Like using http://www.jsonschemavalidator.net/, it will help you with error and fields. Hope this may help!

Related

Json Schema Properties with $ref

Trying to use $ref for the entirety of properties. I can't tell what this is syntax valid but doesn't validate the payload. This should fail but doesn't.
I've also tried "$ref": "file:./ref.json".
schema:
{
"animal": {
"properties":{
"allOf": {"$ref": "file:./ref.json"}
}
},
"required": ["animal"]
}
ref.json:
{
"action":{
"type": "string"
},
"required": ["action"]
}
payload
{
"animal": {
"action": 2
}
}
"allOf": {"$ref": "file:./ref.json"} is not syntactically valid -- the value of an allOf must be an array. (your evaluator should be giving you a warning about this.)
JSON Schema evaluators are not required to support loading external files from disk or the network. Check your documentation for how to add documents to the evaluator so they can be used by $ref. (your evaluator should be giving you a warning when you reference an unknown resource.)
The reason why you are not seeing the above errors is because your overall schema has no recognized keywords in it -- you are missing a "properties": { ... } wrapped around the entire schema. The top level "keyword" is "animal", which is not recognized, therefore there are no recognized keywords anywhere in the schema, therefore there is nothing to make it return an invalid result.

How to validate number of properties in JSON schema

I am trying to create a schema for a piece of JSON and have slimmed down an example of what I am trying to achieve.
I have the following JSON schema:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Set name",
"description": "The exmaple schema",
"type": "object",
"properties": {
"name": {
"type": "string"
}
},
"additionalProperties": false
}
The following JSON is classed as valid when compared to the schema:
{
"name": "W",
"name": "W"
}
I know that there should be a warning about the two fields having the same name, but is there a way to force the validation to fail if the above is submitted? I want it to only validate when there is only one occurrence of the field 'name'
This is outside of the responsibility of JSON Schema. JSON Schema is built on top of JSON. In JSON, the behavior of duplicate properties in an object is undefined. If you want to get warning about this you should run it through a separate validation step to ensure valid JSON before passing it to a JSON Schema validator.
There is a maxProperties constraint that can limit total number of properties in an object.
Though having data with duplicated properties is a tricky case as many json decoding implementions would ignore duplicate.
So your JSON schema validation lib would not even know duplicate existed.

How to validate structure of json using phpleague/json-guard

I'm using Laravel 5.4 for an api and have an endpoint that accepts JSON along the lines of:
{
"input": {
"owner": "name of owner",
"content": [
]
}
}
I want to get only the JSON inside input and ensure that it is valid, both structurally and based on the content.
Using http://json-guard.thephpleague.com and their basic example from the overview page, everything comes back as valid no matter what I change as the input so I assume I am using it wrong.
From their example I have constructed the following. It passes validation. The issue is that I cannot get it to fail.
routes file
Route::post('validate', 'TestController#validateJson');
TestController#validateJson
public function validateJson()
{
$dereferencer = \League\JsonReference\Dereferencer::draft4();
$schema = json_decode('{ "properties": { "id": { "type": "string", "format": "uri" } } }');
$data = json_decode('{ "id": "https://json-guard.dev/schema#" }');
$validator = new \League\JsonGuard\Validator($data, $schema);
if ($validator->fails()) {
return response($validator->errors());
}
return response('all ok');
}
I believe I might need to use the JSON Reference and define a custom schema, but until I can fully understand the example and get it to fail, I don't want to do anything more complicated.
everything comes back as valid no matter what I change as the input so I assume I am using it wrong.
It is hard to say exactly what the issue is without seeing an example of what input you tried. Since the example schema validates that id is a string with the uri format, it should fail when you provide a string that is not a valid URI. The following example will return a format error:
<?php
require __DIR__ . '/vendor/autoload.php';
$schema = json_decode('{ "properties": { "id": { "type": "string", "format": "uri" } } }');
$data = json_decode('{ "id": "hello world" }');
$validator = new \League\JsonGuard\Validator($data, $schema);
echo json_encode($validator->errors(), JSON_PRETTY_PRINT);
There are some parts of JSON Schema that are unintuitive and you might not expect to pass.
A constraint only validates if it applies to that type. If you don't pass an object validation will pass because the properties constraint only applies to objects:
$data = null;
var_dump((new \League\JsonGuard\Validator($data, $schema))->passes()); // true
To make non object inputs fail you need to specify "type": "object". Note that this will also happen with invalid JSON, since json_decode will return null when it fails.
Validation will also pass with an empty object:
$data = json_decode('{}');
var_dump((new \League\JsonGuard\Validator($data, $schema))->passes()); // true
To make the properties required you have to use the required keyword.
I want to get only the JSON inside input and ensure that it is valid, both structurally and based on the content.
This schema should work as a starting point:
{
"type": "object",
"properties": {
"input": {
"type": "object",
"properties": {
"owner": {
"type": "string",
"minLength": 1"
},
"content": {
"type": "array"
}
},
"required": ["owner", "content"],
"additionalProperties": false
}
},
"required": ["input"],
"additionalProperties": false
}
We are requiring that the input is an object, that it has an input property and no other properties, and that input is an object with the properties owner and content. The minLength rule on owner is to prevent an empty string from passing.
I believe I might need to use the JSON Reference and define a custom schema
You can write pretty complex schemas without using JSON Reference at all. It's just a way to reuse a schema without copy and pasting. For example, you might define a 'money' schema and use that for any dollar amounts in your API.
You definitely will need to write a custom schema. The schema replaces the Laravel validation rules you would write for each endpoint otherwise.

json-schema-validator custom message

I am using json-schema-validator2.2.6 library to validate my json against json schema. The problem is that it gives generic error messages that are not relevant to me. I want to send custom message or code to user.
Do we have any option like this :
"properties": {
"myKey": {
"type": "string"
**"errorMessage" : "My error message"**
},
}
Or any other way by which I can provide custom error message?
You can create Custom Error Messages in JSON Schema. Sort Of!(In NodeJS). Lets take an Example -
We have to check a key 'DOB' in JSON which should is a required field and it should be in format 'dd-mmm-yyyy'.
Now we have to use two validation in JSON. First, It should be present and it should follow the pattern of `dd-mmm-yyyy'
Now JSON Schema would be
{
"id": "DOBChecker",
"type": "object",
"properties": {
"DOB": {
"type": "string",
"required": true,
"pattern": "/^(([1-9]|0[1-9]|1[0-9]|2[1-9]|3[0-1])[-](JAN|FEB|MAR|APR|MAY|JUN|JULY|AUG|SEP|OCT|NOV|DEC)[-](\d{4}))$/i",
"message": {
"required": "Date of Birth is Required Property",
"pattern": "Correct format of Date Of Birth is dd-mmm-yyyy"
}
}
}
Now If you have got the error while validations. You will get the whole schema back at errors key array and in that access schema object. The Schema Object will contain exactly same keys as the schema defined above.
You can now access it . The failed Validation name will be in the 'name' key. Now you can access your custom Message using
schema.message[name]

Creating a type definition for a property named "type" using JSON schema

I'm trying to create a JSON schema for an existing JSON file that looks something like this:
{
"variable": {
"name": "age",
"type": "integer"
}
}
In the schema, I want to ensure the type property has the value string or integer:
{
"variable": {
"name": "string",
"type": {
"type": "string",
"enum": ["string", "integer"]
}
}
}
Unfortunately it blows up with message: ValidationError {is not any of [subschema 0]....
I've read that there are "no reserved words" in JSON schema, so I assume a type of type is valid, assuming I declare it correctly?
The accepted answer from jruizaranguren doesn't actually answer the question.
The problem is that given JSON (not JSON schema, JSON data) that has a field named "type", it's hard to write a JSON schema that doesn't choke.
Imagine that you have an existing JSON data feed (data, not schema) that contains:
"ids": [ { "type": "SSN", "value": "123-45-6789" },
{ "type": "pay", "value": "8675309" } ]
What I've found in trying to work through the same problem is that instead of putting
"properties": {
"type": { <======= validation chokes on this
"type": "string"
}
you can put
"patternProperties": {
"^type$": {
"type": "string"
}
but I'm still working through how to mark it as a required field. It may not be possible.
I think, based on looking at the "schema" in the original question, that JSON schemas have evolved quite a lot since then - but this is still a problem. There may be a better solution.
According to the specification, in the Valid typessection for type:
The value of this keyword MUST be either a string or an array. If it is an array, elements of the array MUST be strings and MUST be unique.
String values MUST be one of the seven primitive types defined by the core specification.
Later, in Conditions for successful validation:
An instance matches successfully if its primitive type is one of the types defined by keyword. Recall: "number" includes "integer".
In your case:
{
"variable": {
"name": "string",
"type": ["string", "integer"]
}
}