Search code examples
pythonjsonjsonschemajson-schema-validatorpython-jsonschema

Unable to validate the 'required' properties in an array of a JSON


I have a draft-7JSON schema in a file like this:

{
    "$schema": "http://json-schema.org/draft-07/schema",
    "type": "object",
    "required": [
        "tenantid",
        "owningObjectId",
        "owningObject",
        "cudAction",
        "message"
    ],
    "properties": {
        "tenantid": {
            "type": "string",
            "default": ""
        },
        "owningObjectId": {
            "type": "string",
            "default": ""
        },
        "owningObject": {
            "type": "string",
            "default": "",
            "pattern": "^TeamUser$"
        },
        "cudAction": {
            "type": "string",
            "default": "",
            "pattern": "^c$"
        },
        "messageDateTime": {
            "type": "string",
            "default": ""
        },
        "encrypted": {
            "type": "boolean",
            "default": false
        },
        "message": {
            "type": "array",
            "items": {
                "type": "object",
                "required": [
                    "name",
                    "teamcode",
                    "enabled"
                ],
                "properties": {
                    "name": {
                        "type": "string",
                        "default": ""
                    },
                    "teamcode": {
                        "type": "string",
                        "default": ""
                    },
                    "org": {
                        "type": "string",
                        "default": ""
                    },
                    "enabled": {
                        "type": "boolean",
                        "default": false,
                    },
                    "version": {
                        "type": "string",
                        "default": ""
                    },
                    "orgDisplay": {
                        "type": "string",
                        "default": ""
                    }
                }
            }
        }
    }
}

I am validating JSON/response with this schema below:

# pip install jsonschema
from jsonschema import Draft7validator
def validate_response(response, schema_file_path: str) -> bool:
    """
    Validate the input message based on the input schema provided.
    :reference http://json-schema.org/understanding-json-schema/
    :param response: response received as JSON
    :param schema_file_path: The schema file path
    :return validated: returns True if valid response else False
    """
    validated = True
    with open(schema_file_path, "r") as schema_reader:
        schema = json.loads(schema_reader.read())
    errors = Draft7Validator(schema).iter_errors(response)
    for error in errors:
        print(error.message)
        validated = False
    if validated:
        print(f"Valid response")
    return validated

However, for a JSON like below faulty_json_response where the message field value array is empty and none of the required properties exists under the message field, the validator does not throw any error. What may be the cause?

faulty_json_response = {
        "tenantid": "5e3bb57222b49800016b666f",
        "owningObjectId": "5e680018ceb7d600012e4375",
        "owningObject": "TeamUser",
        "cudAction": "c",
        "messageDateTime": "1584460716.01416",
        "encrypted": false,
        "message": [],
    }

Please let me know if more details needed. Thank you.


Solution

  • The items keyword applies the subschema value (which includes our required), to each item in the applicable array (message in your case).

    Given you have no items IN the message array, the subschema isn't applied, and so you don't get any validation errors.

    If you want to specifiy the array has a minimum number of items, you can do that with the minItems keyword...

    The value of this keyword MUST be a non-negative integer.

    An array instance is valid against "minItems" if its size is greater than, or equal to, the value of this keyword.

    Omitting this keyword has the same behavior as a value of 0.

    https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-validation-01#section-6.4.4

    You can see this in action in this live demo https://jsonschema.dev/s/yMM0c