Dainis Abols Dainis Abols - 4 months ago 32
JSON Question

How to validate required items of JSON SCHEMA array

I have a JSON Schema for new orders, that consists of order list and address.

{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"properties": {
"order": {
"type": "array",
"items": {
"type": "array",
"properties": {
"product_id": {
"type": "integer"
},
"quantity": {
"type": "integer"
}
},
"required": [
"product_id",
"quantity"
]
}
},
"address": {
"type": "array",
"properties": {
"name": {
"type": "string"
},
"phone": {
"type": "integer"
},
"address1": {
"type": "string"
},
"address2": {
"type": "string"
},
"city": {
"type": "string"
},
"state_or_region": {
"type": "string"
},
"country": {
"type": "string"
}
},
"required": [
"name",
"phone",
"address1",
"city",
"state_or_region",
"country"
]
}
},
"required": [
"order",
"address"
]
}


But it doesn't seem to actually validate the items at all (I'm using
Laravel 5.2
with
"justinrainbow/json-schema": "~2.0"
):

$refResolver = new \JsonSchema\RefResolver(new \JsonSchema\Uri\UriRetriever(), new \JsonSchema\Uri\UriResolver());
$schema = $refResolver->resolve(storage_path('schemas\orders.post.json'));

$errors = [];
$input = Request::input();

// Validate
$validator = new \JsonSchema\Validator();
$validator->check($input, $schema);

$msg = [];
if ($validator->isValid()) {
return Response::json(['valid'], 200, [], $this->pritify);
} else {
$msg['success'] = false;
$msg['message'] = "JSON does not validate";
foreach ($validator->getErrors() as $error) {
$msg['errors'][] = [
'error' => ($error['property'] = ' ') ? 'wrong_data' : $error['property'],
'message' => $error['message']
];
}
return Response::json($msg, 422, [], $this->pritify);
}


A request like this always comes valid:

{
"order": [
{
"product_id": 100,
"quantity": 1
},
{
"product_id": 0,
"quantity": 2
}
],
"address": []
}


Any ideas what am I doing wrong?

Answer

You have messed array and object types. The only array value in your scheme must be order. Fixed scheme:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "order": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "product_id": {
            "type": "integer"
          },
          "quantity": {
            "type": "integer"
          }
        },
        "required": [
          "product_id",
          "quantity"
        ]
      }
    },
    "address": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "phone": {
          "type": "integer"
        },
        "address1": {
          "type": "string"
        },
        "address2": {
          "type": "string"
        },
        "city": {
          "type": "string"
        },
        "state_or_region": {
          "type": "string"
        },
        "country": {
          "type": "string"
        }
      },
      "required": [
        "name",
        "phone",
        "address1",
        "city",
        "state_or_region",
        "country"
      ]
    }
  },
  "required": [
    "order",
    "address"
  ]
}

And validation errors I got with you test data:

JSON does not validate. Violations:
[address.name] The property name is required
[address.phone] The property phone is required
[address.address1] The property address1 is required
[address.city] The property city is required
[address.state_or_region] The property state_or_region is required
[address.country] The property country is required
Comments