0

I have following JSON schema:

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "type": "object",
    "additionalProperties": false,
    "properties": {
        "Payload": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
                "Person": {
                    "type": "array",
                    "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "properties": {
                            "Id": {
                                "type": "string"
                            },
                            "Name": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "Id",
                            "Name"
                        ]
                    }
                }
            }
        },
        "Reference": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
                "Status": {
                    "anyOf": [
                        {
                            "Passed": {
                                "type": "string"
                            },
                            "Failed": {
                                "type": "string"
                            }
                        }
                    ]
                }
            }
        }
    },
    "anyOf": [
        {
            "additionalProperties": false,
            "properties": {
                "Status": {
                    "type": "string",
                    "enum": [
                        "Failed"
                    ]
                }
            },
            "required": [
                "Reference"
            ],
            "not": {
                "required": [
                    "Payload"
                ]
            }
        },
        {
            "additionalProperties": true,
            "properties": {
                "Status": {
                    "type": "string",
                    "enum": [
                        "Passed"
                    ]
                }
            },
            "required": [
                "Reference"
            ]
        }
    ]
}

I want to check if JSON message has status failed then person array should not be present. It should be present only if status is passed.

I tried following solution here but definitely i am doing something wrong as validator passes with Failed status and person details present. Can someone tell what I may be doing wrong?

tom redfern
  • 30,562
  • 14
  • 91
  • 126
Kryptonian
  • 860
  • 3
  • 10
  • 26

1 Answers1

1

You have a few issues.

/properties/Reference/properties/Status

This isn't a valid schema. It looks like you're trying to describe an enum.

additionalProperties

The reason is complicated, but the conditional patterns don't work with additionalProperties. The good news is it's also unnecessary. You can just leave those out.

/anyOf

Looks like you're using the "Enum" pattern, but the implication pattern is better in this case because only one of the enum states has additional constraints.

Conditional on nested property

Your schemas that define the Reference.Status value are actually just pointing to Status. You need a schema that describes the parent property as well.


The following does what I think your schema was trying to do.

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "Payload": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "Person": {
          "type": "array",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "Id": { "type": "string" },
              "Name": { "type": "string" }
            },
            "required": ["Id", "Name"]
          }
        }
      }
    },
    "Reference": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "Status": { "enum": ["Passed", "Failed"] }
      }
    }
  },
  "anyOf": [
    {
      "not": {
        "properties": {
          "Reference": {
            "properties": {
              "Status": { "enum": ["Failed"] }
            },
            "required": ["Status"]
          }
        },
        "required": ["Reference"]
      }
    },
    { "not": { "required": ["Payload"] } }
  ]
}
Jason Desrosiers
  • 22,479
  • 5
  • 47
  • 53
  • Thanks a lot :)The comments and snippet really helped me out. The actual schema was a bit different and I had created new schema to explain the case due to which /properties/Reference/properties/Status came in. I will correct the question later. – Kryptonian Sep 25 '19 at 04:35