Home > Blockchain >  Validate every JSON Object item in JSON Array with fastjsonschema in Python
Validate every JSON Object item in JSON Array with fastjsonschema in Python

Time:01-14

I'm working with fastjsonschema to validate JSON objects that contain a list of product details.

If the object is missing a value, the validation should create it with the default value e.g.

validate = fastjsonschema.compile({
'type': 'object',
'properties': {
    'a': {'type': 'number', 'default': 42},
},
})
data = validate({})
assert data == {'a': 42}

But with an array, it will only fill out the defaults for as many of the array objects as you define in the schema. Which means that if the user enters more array items than the schema covers, the extra items will not be validated by the schema.

Is there a way to declare that all items in the array will follow the same schema, and that they should all be validated?

Currently when I define in the schema

{
    "products": {
        "type": "array",
        "default": [],
        "items":[
              {
                "type": "object",
                "default": {},
                "properties": {
                    "string_a": {
                        "type": "string",
                        "default": "a"
                    },
                    "string_b": {
                        "type": "string",
                        "default": "b"
                    }
              }
        ]
    }
}

What will happen when I try to validate

{"products":[{},{}]}

is that it becomes

{"products":[{"string_a":"a","string_b":"b"},{}]}

This can cause issues with missing data, and of course it's better to have the whole thing validated.

So is there a way to define a schema for an object in an array, and then have that schema applied to every item in the array?

Thanks

CodePudding user response:

You've got an extra array around your items schema. The way you have it written there (for json schema versions before 2020-12), an items with an array will specify the schema for each item individually, rather than all of them:

"items": [
  { .. this schema is only used for the first item .. },
  { .. this schema is only used for the second item .. },
  ...
]

compare to:

"items": {  .. this schema is used for ALL items ... }

(The implementation really shouldn't be filling in defaults like that anyway, as that's contrary to the specification, but that's orthogonal.)

  •  Tags:  
  • Related