jsonschematv4

JsonSchema is not validated with oneOf


Need help to find the bug with this schema. It has oneOf operator. Schema is here :

   `{
    "type": "object",
    "required": [
        "type",
        "body"
    ],
    "properties": {
        "type": {
            "description": "type of the document to post",
            "type": "string",
            "enum": [
                "123",
                "456"                    
            ]
        },
        "body": {
            "type": "object",
            "description": "body",
            "oneOf": [{
                "$ref": "#/definitions/abc",
                "$ref": "#/definitions/def"
            }]
        }
    },
    "definitions": {
        "abc": {                
            "type": "array",
            "description": "abc",
           "properties" : {
               "name" : { "type" : "string"  }
         }
        },
        "def": {                
            "type": "array",
            "description": "users","properties" : {
               "name" : { "type" : "string"  }
         }
        }
    }
}`

My Json is this :

  `{
            "type": "123",
            "body": {
                "abc": [{
                    "name": "test"
                }]
            }
        }`

It does not validate with tv4 and I also tried this online tool. It works without oneOf operator. Otherwise it does not validate it any tool.

Edit :

After reading the answers I modified the schema. New schema is :

{
"type": "object",
"properties": {
    "type": {
        "description": "type of the document to post",
        "type": "string",

    },
    "body": {
        "type": "object",
        "description": "body",
        "properties": {
            "customers": {
                "type": "array"
            }
        },
        "anyOf": [
            {
                "title": "customers prop",
                "properties": { 
                    "customers": {
                        "type": "array",
                        "description": "customers",
                        "items": {
                            "type": "object",
                            "properties": {
                                "name": {
                                    "type": "string"
                                }
                            }
                        }
                    }
                }
            }
        ]
    }
  }
}

And json is here

{
"type": "customer",
"body": {
    "none": [
        {
            "name": "test"
        }
    ]
  }
}

But it validates. I want to enforce one of "customers" or "users" in the body. To test I have removed users from the body.

Pl help.


Solution

  • Since you have the type at root level, you probably want the oneOf statement to check that an object with type "customer" has customers in the body (even though I would suggest skipping the body and placing customers and users directly in root object).

    This works with your example, will require that an object with type "customer" has a body with "customers", and to clarify the matching, I let customer have the property "name" while the user has "username":

    {
      "type": "object",
      "properties": {
        "type": { "type": "string" },
        "body": {
          "type": "object",
          "properties": {
            "customers": { 
              "type": "array",
              "items": { "$ref": "#/definitions/customer" }
            },
            "users": {
              "type": "array",
              "items": { "$ref": "#/definitions/user" }
            }
          }
        }
      },
      "definitions": {
        "customer": {
          "type": "object",
          "properties": { "name": { "type": "string" } },
          "required": [ "name" ]
        },
        "user": {
          "type": "object",
          "properties": { "username": { "type": "string" } },
          "required": [ "username" ]
        }
      },
      "oneOf": [
        {
          "properties": {
            "type": {
              "pattern": "customer"
            },
            "body": {
              "required": [ "customers" ]
            }
          }
        },
        {
          "properties": {
            "type": {
              "pattern": "user"
            },
            "body": {
              "required": [ "users" ]
            }
          }
        }
      ]
    }