Chums
Chums

Reputation: 1

JSON Validation using AJV

I have the following JSON validation

var schema = {
    "type": "object",
    "required": ["name", "profession"],
    "properties": {
        "name": { "type": "string" },
        "profession": {
            "oneOf": [
                { "$ref": "#/definitions/developer" },
                { "$ref": "#/definitions/manager" }
            ]
        }
    },
    "definitions": {
        "developer": {
            "type": "object",
            "properties": {
                "jobLevel": { "$ref": "#/definitions/jobLevels" },
                "linesOfCode": { "type": "number" },
                "languages": { "enum": ["C++", "C", "Java", "VB"] }
            },
            "required": ["jobLevel"]
        },
        "manager": {
            "type": "object",
            "properties": {
                "jobLevel": { "$ref": "#/definitions/jobLevels" },
                "peopleManaged": { "type": "number" },
                "responsibilities": {
                    "type": "array",
                    "minItems": 1,
                    "items": "string",
                    "uniqueItems": true
                }
            },
            "required": ["jobLevel"]
        },
        "jobLevels": { "enum": ["Beginner", "Senior", "Expert"] }
    }
}

I try to validate the following JSON string with the above validation string.

 var validate = ajv.compile(schema);
 var valid = validate({
     "name": "David",
     "profession": {
         "jobLevel": "Expert",
         "linesOfCode": 50000,
         "languages": "Java"
     },
 });

Here I get the message "data.profession should match exactly one schema in oneOf" eventhough I provide exactly one instance with the correct instance variables and such in the data. Could you please tell me what I am doing wrong here? I a using the AJV validator by the way.

Thank you.

Upvotes: 0

Views: 1375

Answers (1)

esp
esp

Reputation: 7677

The problem here is that the object for profession object is valid according to both schemas inside oneOf keyword, and the spec requires that it is valid against exactly one schema: https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#oneof

The reason for it being valid according to both schemas is because additional properties are allowed.

You can:

  • use anyOf (it would be faster in 50% of cases, as it will stop validation when the 1st schema succeeds)
  • use additionalProperties: false to disallow additional fields

Upvotes: 1

Related Questions