Search code examples
javajsonspring-bootjsonschemajson-schema-validator

"prefixItems" of JSON Schema draft 2020-12 validating only first element of the array


I am using the following schema to validate json. When I have more than one element in the array of appData, it validates only the first index of the array. The other indexes are not validated.

How does prefixItems evaluate a json instance?

    {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {
            "appName": {
                "type": "string"
            },
            "appData": {
                "type": "array",
                "prefixItems": [
                    {
                        "type": "object",
                        "properties": {
                            "appReference": {
                                "type": "string"
                            },
                            "tableName": {
                                "type": "string"
                            },
                            "beginDate": {
                                "type": "string",
                                "pattern": "^[0-9]{1,2}\\/[0-9]{1,2}\\/[0-9]{4}$",
                                "description": "Use regex to validate this string as a date"
                            },
                            "isTrueBeginDate": {
                                "type": "string"
                            },
                            "paid": {
                                "type": "string"
                            },
                            "amount": {
                                "type": "null"
                            }
                        },
                        "required": [
                            "appReference",
                            "tableName",
                            "beginDate",
                            "paid",
                            "amount"
                        ]
                    }
                ]
            }
        },
        "required": [
            "appName",
            "appData"
        ]
    }

I am using the following maven dependency to validate the json in java.

    <dependency>
          <groupId>com.networknt</groupId>
          <artifactId>json-schema-validator</artifactId>
          <version>1.4.0</version>
        </dependency>

Solution

  • prefixItems is meant to define a tuple and will only validate each index defined in the prefixItems array.

    take this example

    {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "array",
        "prefixItems": [
            {
                "type": "boolean"
            },
            {
                "type": "string"
            },
            {
                "type": "number"
            }
        ]
    }
    

    passing

    [true, "test", 1]
    

    failing

    [true, true, 1]
    

    src: https://json-schema.org/understanding-json-schema/reference/array#tupleValidation


    If you want to validate all of your array indexes with the same schema, you can use items keyword which validates all array indexes

    {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {
            "appName": {
                "type": "string"
            },
            "appData": {
                "type": "array",
                "items":
                    {
                        "type": "object",
                        "properties": {
                            "appReference": {
                                "type": "string"
                            },
                            "tableName": {
                                "type": "string"
                            },
                            "beginDate": {
                                "type": "string",
                                "pattern": "^[0-9]{1,2}\\/[0-9]{1,2}\\/[0-9]{4}$",
                                "description": "Use regex to validate this string as a date"
                            },
                            "isTrueBeginDate": {
                                "type": "string"
                            },
                            "paid": {
                                "type": "string"
                            },
                            "amount": {
                                "type": "null"
                            }
                        },
                        "required": [
                            "appReference",
                            "tableName",
                            "beginDate",
                            "paid",
                            "amount"
                        ]
                    }
                
            }
        },
        "required": [
            "appName",
            "appData"
        ]
    }
    

    passing

    {
        "appName": "test",
        "appData": [
            {
                "appReference": "thing",
                "tableName": "table-one",
                "beginDate": "01-01-2017",
                "paid": "1.50",
                "amount": null
            },
            {
                "appReference": "thing-two",
                "tableName": "table-two",
                "beginDate": "01-01-2017",
                "paid": "1.50",
                "amount": null
            },
            {
                "appReference": "thing-three",
                "tableName": "table-three",
                "beginDate": "01-01-2017",
                "paid": "1.50",
                "amount": null
            },
            {
                "appReference": "thing-four",
                "tableName": "table-four",
                "beginDate": "01-01-2017",
                "paid": "1.50",
                "amount": null
            }
        ]
    }