Search code examples
jsonjsonschemaajv

JSON schema for variable length array with some fixed items


I am trying to define a schema to validate this type of data array:

[ 
'item1 string',         // item1, being a given string
2,                      // item2, an integer
'item3 string',         // item3, a variable string, repeated N times
'another item3 string', // ...
...
'last item3 string',    //
1.1,                    // item4, a number
]

item3 is a collection of strings, which varies. Without the repetition, a simplified version of my schema is:

{
  type: 'array',
  minItems: 4,
  maxItems: 4,
  items: [
    { $ref: '#/definitions/item1' },
    { $ref: '#/definitions/item2' },
    { $ref: '#/definitions/item3' },
    { $ref: '#/definitions/item4' },
  ],
  definitions: {
    item1: { type: 'string' },
    item2: { type: 'integer' },
    item3: { type: 'string' },
    item4: { type: 'number' },
  },
}

I want my "items" section to be an array, as I want to make sure the items are ordered in the right way. But I don't see how to describe the repetition of "item3" elements.

I actually know in advance the number of "item3" occurrences I am expecting, so right now I rebuild the schema for each check (adjusting the mix/maxItems, and repeating the item3 section).

But it there a more efficient way of going about this? This schema is used in nodejs / ajv, is there an ajv feature that would help if this is not doable inside a schema? Thank you.


Solution

  • This is not something that can be expressed with JSON Schema. If the variable length array items came last, it could be done. Assuming it would be ok to move item4 before item3, you could do this...

    {
      "type": "array",
      "items": [
        { "$ref": "#/definitions/item1" },
        { "$ref": "#/definitions/item2" },
        { "$ref": "#/definitions/item4" }
      ],
      "additionalItems": { "$ref": "#/definitions/item3" }
    }
    

    If you can't move the variable items to the end, you're out of luck.