6

I was looking around the docs and couldn't find any direct or indirect solution.

Is there any way to get validation on JSON objects without knowing exactly where the specific object is located?

For example, I want to validate the following sub-object:

{
  "grandParent": {
    "parent": {
      "child": {
        "name": "John"
      }
    }
  }
}

The object can be part of a larger JSON file the can be structured as follows:

{
  "root": {
    "someKey": {
      "grandParent": ...
    },
    "grandParent": ...,
    ...<go in even deeper>: {
      "grandParent": ...
    }
  }
} 

Can I create a json schema that validates the object no matter where it is?

Similar example in glob would be: root.**.grandParent.parent.child

  • You can, but I have to ask, are you sure you WANT to do this? Have you considered using JSON-LD to allow easy extraction of the right parts to validate? Obviously, that's not helpful if you don't control the source data. – Relequestual Apr 29 '21 at 09:56
  • I don't think JSON-LD can help. I don't control the object I'm getting and have no way of knowing where this object I need to validate might appear. In most cases it will only appear once so converting it to JSON-LD dynamically won't do much (I think) – Dima Brusilovsky Apr 29 '21 at 10:06
  • Ok, sure. I think I have a solution for you =] – Relequestual Apr 29 '21 at 10:07

1 Answers1

1

You'll need to use a combination of additionalProperties, items, and recursive references.

First, we define the structure you want to validate. You have to define properties for each layer of the object.

Next, you want your root level to reference that definition. Because you're using pre draft 2019-09, you'll need to wrap that reference in an allOf.

Then you want to make sure that for objects, the values have the root schema applied, and for arrays, each item has the root schema applied.

The use of "$ref": "#" resolves to the root of the schema, which creates the cyclical reference.

Some implementations may not like this, but most should be able to handle it.

Here's a live demo of the below schema: https://jsonschema.dev/s/lBrZk

{
  "$schema": "http://json-schema.org/draft-07/schema",
  "definitions": {
    "grandParentToChild": {
        "properties": {
          "grandParent": {
            "properties": {
              "parent": {
                "properties": {
                  "child": {
                    "properties": {
                      "name": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        }
    }
  },
  "allOf": [
    {
      "$ref": "#/definitions/grandParentToChild"
    }
  ],
  "additionalProperties": {
    "$ref": "#"
  },
  "items": {
    "$ref": "#"
  }
}
Relequestual
  • 11,631
  • 6
  • 47
  • 83