Arcturus13
Arcturus13

Reputation: 11

Can you use separate files for json subschemas?

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"]
        }
    }
}

Upvotes: 1

Views: 754

Answers (1)

Ether
Ether

Reputation: 53966

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).

Upvotes: 1

Related Questions