0

I have two JSON schemas - publisher and article, such that there could be multiple articles in a single publisher.

This is the article schema (in a.json):

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Article",
  "type": "object",
  "properties": {
    "aid": {
      "type": "integer"
    },
    "author": {
      "type": "string"
    },
    "title": {
      "type": "string"
    }
  },
  "required": ["aid", "author", "title"]
}

And I'm trying to reference this in publisher schema as below (in p.json, in the same dir):

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Publisher",
  "type": "object",
  "properties": {
    "pid": {
      "type": "integer"
    },
    "name": {
      "type": "integer"
    },
    "lang": {
      "type": "string"
    },
    "articles": {
      "type": "array",
      "uniqueItems": true,
      "items": {
        "type": "object",
        "$ref": "./a.json"
      }
    }
  },
  "required": ["pid", "articles"]
}

I would ideally want the data to raise error if any of the articles do not have the required fields as mentioned in a.json. But this does not seem to happen:

import json, jsonschema

schema = json.load(open("p.json"))
data = {
  "pid": 1,
  "articles": [
    {
      "aid": 100,
      "title": "test",
    }
  ]
}
jsonschema.validate(data, schema)

The last line should raise an exception, as article does not have the author key that is marked as a requierd field in a.json.

But somehow, it raises _WrappedReferencingError: Unresolvable: ./a.json exception.

How can I reference a.json here such that it raise the correct exception?

2 Answers 2

3

Some implementations understand filesystem references natively, but the implementation you're using doesn't. You need to configure it to map the p.json URI to your schema. I'm just going off of the documentation, but it looks like you would do something like this,

from referencing import Registry, Resource
from jsonschema import Draft202012Validator

article = json.load(open("a.json"))
publisher = json.load(open("p.json"))

registry = Registry().with_resources(
    [
        ("http://example.com/a.json", Resource.from_contents(article))
    ],
)

validator = Draft202012Validator(publisher, registry=registry)
validator.validate(data)

In addition, you'll need to add "$id": "http://example.com/p.json" to your p.json schema. That gives the implementation a base URI to use to resolve the a.json reference in the p.json schema. That makes the reference resolve to http://example.coma/a.json which matches a schema in the registry.

Sign up to request clarification or add additional context in comments.

1 Comment

@Shod, if it doesn't make sense to use an http(s):, you should know that you can use any URI to identify your schemas; just make sure that the $refs match them. If you're going to use relative URIs in your references (e.g. a.json), the URIs need to support paths.
-1

The way you outlined your schemas is correct. Your error is the trailing comma on title. This is invalid JSON itself, not even JSON Schema.

6 Comments

the JSON is valid - the comma is for properties, not title
You have a comma in your instance data = { "pid": 1, "articles": [ { "aid": 100, "title": "test", } ] }
ah, that's python, not JSON exactly, and this is allowed in python.
the data instance should be valid json, regardless of the language used. if you remove the trailing comma in that line, the instance validates successfully
did you try that in python? when you print data, or do print(json.dumps(data, indent=4)), it will print without the comma
|

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.