Search code examples
jsonjsonschemajson-schema-validator

Trying the get the JSON Schema specification's example meta-schema to work


I am trying to get to work the meta-schema example in the the JSON Schema specification.

I put the new main meta-schema into a file that I named new-main-meta-schema.json

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/meta/general-use-example",
  "$dynamicAnchor": "meta",
  "$vocabulary": {
    "https://json-schema.org/draft/2020-12/vocab/core": true,
    "https://json-schema.org/draft/2020-12/vocab/applicator": true,
    "https://json-schema.org/draft/2020-12/vocab/validation": true,
    "https://example.com/vocab/example-vocab": true
  },
  "allOf": [
    {"$ref": "https://json-schema.org/draft/2020-12/meta/core"},
    {"$ref": "https://json-schema.org/draft/2020-12/meta/applicator"},
    {"$ref": "https://json-schema.org/draft/2020-12/meta/validation"},
    {"$ref": "https://example.com/meta/example-vocab"}
  ],
  "patternProperties": {
    "^unevaluated": false
  },
  "properties": {
    "localKeyword": {
      "$comment": "Not in vocabulary, but validated if used",
      "type": "string"
    }
  }
}

That meta-schema references a new extension schema. I put it into a file that I named extension-schema.json

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/meta/example-vocab",
  "$dynamicAnchor": "meta",
  "$vocabulary": {
    "https://example.com/vocab/example-vocab": true
  },
  "type": ["object", "boolean"],
  "properties": {
    "minDate": {
      "type": "string",
      "pattern": "[0-9]{4}-[0-9]{2}-[0-9]{2}",
      "format": "date"
    }
  }
}

Now I created a schema that conforms to the new meta-schema. I put the schema into a file that I named schema.json

{
    "$schema": "https://example.com/meta/general-use-example",
    "type": "object",
    "properties": {
        "departingGate": {"type": "string"},
        "minDate": "2023-08-07"
    }
}

Then I created an instance of the schema. I put the instance into a file that I named instance.json

{
   "departingGate": "Gate 26"
}

Does all that look correct?

Next, I wanted to validate instance.json against schema.json so I opened my browser to the online JSON Schema validator tool Hyperjump. I copied the content of new-main-meta-schema.json into the schema portion of the online tool. Immediately the tool responded with this error message:

Error: Unrecognized vocabulary: https://example.com/vocab/example-vocab. You can define this vocabulary with the 'defineVocabulary' function.

Is there any way to run this example in Hyperjump's online schema validator? If not, is there an online schema validator that can run this example?


Solution

  • Is there any way to run this example in Hyperjump's online schema validator?

    With a couple tweaks, yes. Some parts of defining a custom dialect require code. Anything that requires code, can't be done in the online tool.

    Your example creates a custom keyword called minDate. In order for the validator to know how to evaluate that keyword, you need to provide a keyword implementation in JavaScript (or TypeScript). You can't provide code online, but if your keyword is only an annotation (always validates to true), you can make the vocabulary that keyword is in optional and avoid having to write code.

    Here's how you make the vocabulary optional.

      "$vocabulary": {
        "https://json-schema.org/draft/2020-12/vocab/core": true,
        "https://json-schema.org/draft/2020-12/vocab/applicator": true,
        "https://json-schema.org/draft/2020-12/vocab/validation": true,
        "https://example.com/vocab/example-vocab": false // <-- This changed to false
      },
    

    It's in the vocab meta-schema too. There's actually no reason to use $vocabulary here, so just remove it.

      // Delete these lines
      "$vocabulary": {
        "https://example.com/vocab/example-vocab": true
      },
    

    Now it will work in the online validator. If you haven't figured it out yet, you can add additional tabs to the schemas panel using the [+] button. The first tab is always the entry point. That's where the schema you created will go. The dialect meta-schema and the vocabulary meta-schema will go in the "Schema 2" and "Schema 3" tabs that you open. WARNING: To avoid a bug, add the meta-schemas first before you paste your schema into the main Schema tab.

    At this point you'll get an invalid schema error, because your schema isn't valid. I think you meant something like this,

      "departureDate": { "minDate": "2023-08-07" } // <-- The `minDate` keyword needed to be inside a schema