1

I have data that comes back from GraphQL, I'd like to verify that data with JSON schema before manipulating it.

There might be a better way of doing this in graphQL than I currently am, but the data that comes back can be of two types with the same properties:

e.g. a simplified version of the data

obj: {
  audio: {
    artists: []
  },
  video: {}
}

or

obj: {
  audio: {},
  video: {
    artists: []
  }
}

So validity would be:

  • an object with both a audio and video property
  • an object with audio as an object with a property artists and an empty property video object
  • an object with video as an object with a property artists and an empty property audio object
  • neither audio or video should be empty together
  • neither audio or video should have properties together

I've built a simplified schema that looks like this:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "file://schemas/simple.schema.json",
  "title": "simplified data",
  "description": "simple",
  "type": "object",
  "properties": {
    "audio": {
      "type": "object"
    },
    "video": {
      "type": "object"
    }
  },
  "oneOf": [
    {
      "audio": {
        "type": "object",
        "properties": {
          "artists": {
            "type": "array"
          }
        }
      },
      "video": {
        "type": "object",
        "properties": {}
      }
    },
    {
      "audio": {
        "type": "object",
        "properties": {}
      },
      "video": {
        "type": "object",
        "properties": {
          "artists": {
            "type": "array"
          }
        }
      }
    }
  ]
}

but AJV doesn't seem to validate the data correctly when run against:

{
  "audio": {
    "artists": []
  },
  "video": {}
}

What might have I got wrong with my schema?

1 Answer 1

3

After an initial attempt, Jason pointed out a simpler solution...

Using oneOf, you can specify that only one of the objects may have at least one property.

You can test this here: https://jsonschema.dev/s/SSRaL

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "file://schemas/simple.schema.json",
  "properties": {
    "audio": {
      "type": [
        "object"
      ],
      "properties": {
        "artists": {
          "$comment": "whatever validation you want"
        }
      }
    },
    "video": {
      "type": [
        "object"
      ],
      "properties": {
        "artists": {
          "$comment": "whatever validation you want"
        }
      }
    }
  },
  "oneOf": [
    {
      "properties": {
        "video": {
          "minProperties": 1
        }
      }
    },
    {
      "properties": {
        "audio": {
          "minProperties": 1
        }
      }
    }
  ]
}
Sign up to request clarification or add additional context in comments.

2 Comments

The if/thens aren't necessary. The oneOf is enough. Also "not": { "additionalProperties": false } can be simplified as "minProperties": 1.
Yeah actually you're right. I added the oneOf after the other parts of the schema. I'll update the answer to reflect. Thanks.

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.