4

I'm writing a schema using draft/2020-12 to validate an array of multiple objects. I will be using YAML for the examples for readability (and it's YAML documents that are going to be validated).

I've seen many different approaches but none seem to do a very good job for some reason.

The data to validate

pipeline:
  - foo: abc
    someOption: 123
  - baz: def
    anotherOption: 223
  - foo: ghi

As you can see, the pipeline array contains objects that has completely different properties. The same object types can appear multiple times (there's 2 instances of an object containing foo, they are to be seen as the same object type).

Schema

$id: 'https://example.com/schema'
$schema: 'https://json-schema.org/draft/2020-12/schema'
type: object
properties: 
  pipeline:
    type: array
    additionalItems: false
    anyOf:
      - items:
          type: object
          additionalProperties: false
          properties:
            foo:
              type: string
            someOption: 
              type: integer
          required: [foo]
      - items:
          type: object
          additionalProperties: false
          properties:
            baz: 
              type: string
            anotherOption:
              type: integer
          required: [baz]

To me, this looks correct, although it fails validation and I can't quite see why...

Even if it had worked, I'm not sure if I'm supposed to use anyOf or oneOf in this case. Is it matching across all array items or per individual array item?

1
  • 1
    additionalItems was removed from the 2020-12 spec. jsonschemavalidator.net does not handle 2020-12 yet. json-schema.hyperjump.io does handle 2020-12. Besides, I think you can remove your use of it, as it would cause validation to fail. It is being ignored right now though, regardless. Commented Jan 26, 2022 at 11:56

1 Answer 1

5

You have it slightly wrong. Currently your schema says... for the pipeline array, either, all of the items must be foo or all of the items must be baz.

You need to change your location of anyOf and items...

items applies to every item in the array. anyOf checks that any of the subschema values are valid against the instance location (in this case, each item in the array).

{
  "$id": "https://example.com/schema",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "pipeline": {
      "type": "array",
      "items": {
        "anyOf": [
          {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "foo": {
                "type": "string"
              },
              "someOption": {
                "type": "integer"
              }
            },
            "required": [
              "foo"
            ]
          }, {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "baz": {
                "type": "string"
              },
              "anotherOption": {
                "type": "integer"
              }
            },
            "required": [
              "baz"
            ]
          }
        ]
      }
    }
  }
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you! I was sure this was one of the variations I had already tested, but now when I tried it again it seems to work.
additionalItems should still be removed from the schema, as it does nothing in draft2020-12.
Thanks @Ether, I'll update to reflect.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.