1

I am new to using JSON schemas and I am pretty confused about subschemas. I have done many searches and read https://json-schema.org/understanding-json-schema/structuring.html but I feel like I am not getting some basic concepts.

I'd like to break up a schema into several files. For instance, I have a metric schema that I would like nested in a category schema. Can a subschema be a separate file that is referenced or is it a block of code in the same file as the base schema? If they are separate files, how do you reference the other file? I have tried using a lot of various values for $ref with the $id of the nested file but it doesn't seem to work.

I don't think I really understand the $id and $schema fields. I have read the docs on them but leave still feeling confused. Does the $id need to be a valid URI? The docs seem to say that they don't. And I just copied the $schema value from the jsonschema site examples.

Any help would be appreciated about what I am doing wrong.

(added the following after Ether's reply) The error messages I get are:

KeyError: 'http://mtm/metric'

and variations on

jsonschema.exceptions.RefResolutionError: HTTPConnectionPool(host='mtm', port=80): Max retries exceeded with url: /metric (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fe9204a31c0>: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known'))

Here is the category schema in category_schema.json:

{
    "$id": "http://mtm/category",
    "$schema":"https://json-schema.org/draft/2020-12/schema",
    "title":"Category Schema",
    "type":"object",
    "required":["category_name", "metrics"],
    "properties": {
        "category_name":{
            "description": "The name of the category.",
            "type":"string"
        },
        "metrics":{
            "description": "The list of metrics for this category.",
            "type":"array",
            "items": { 
                "$ref": "/metric" 
            }
        }
    }
}

And here is the metric schema in metric_schema.json:

{
    "$id": "http://mtm/metric",
    "$schema":"https://json-schema.org/draft/2020-12/schema",
    "title":"Metric Schema",
    "description":"Schema of metric data.",
    "type":"object",
    "required": ["metric_name"],
    "properties": {
        "metric_name":{
            "description": "The name of the metric in standard English. e.g. Live Views (Millions)",
            "type":"string"
        },
        "metric_format": {
            "description": "The format of the metric value. Can be one of: whole, decimal, percent, or text",
            "type": "string",
            "enum": ["integer", "decimal", "percent", "text"]
        }
    }
}
Arcturus13
  • 11
  • 2
  • I've been working on updating the Understanding JSON Schema site and would really appreciate any feedback you have about what you are finding confusing. https://github.com/json-schema-org/understanding-json-schema/ – Jason Desrosiers Jul 29 '21 at 19:20

1 Answers1

1

Yes, you can reference schemas in other documents, but the URIs need to be correct, and you need to add the files manually to the evaluator if they are not network- or filesystem-available.

In your first schema, you declare its uri is "http://mtm/category". But then you say "$ref": "/mtm/metric" -- since that's not absolute, the $id URI will be used as a base to resolve it. The full URI resolves to "http://mtm/mtm/metric", which is not the same as the identifier used in the second schema, so the document won't be found. This should be indicated in the error message (which you didn't provide).

Ether
  • 53,118
  • 13
  • 86
  • 159
  • Thanks, Ether, that certainly helps me understand things a bit more. I saw in the error log how it was resolving to what you said it would. I modified the metric ref to reflect the use of relative paths. I get a key error still a similar error and I added that to my original post. It is KeyError: 'http://mtm/metric'. Both files are in the same folder. What does it mean to "add the files manually to the evaluator if they are not network- or filesystem-available"? Thanks :) – Arcturus13 Jul 28 '21 at 14:29
  • You'd have to check the documentation for your particular implementation to see how to do it, but in general, documents referenced with "$ref" are not expected to be network-retrievable, so if your schema depends on external documents, you need to tell the evaluator about them in advance so it can load them and have them available at evaluation time. – Ether Jul 28 '21 at 19:14