Is it possible to import the entire $defs
section from an external schema (using JSON Schema draft 2020)?
For example, let's say I have a set of three schemas like this:
"base"
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/schemas/base",
"$defs": {
"abc": {
"type": "string",
"pattern": "^[abcABC] $"
}
},
"type": "object",
"properties": {
"baseprop1": {
"title": "base property 1",
"$ref": "#/$defs/abc"
},
"baseprop2": {
"title": "base property 2",
"$ref": "#/$defs/abc"
}
}
}
"better"
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/schemas/better",
"$ref": "https://example.com/schemas/base",
"type": "object",
"properties": {
"betterprop": {
"title": "an additional, even better property!",
"$ref": "base#/$defs/abc"
}
}
}
"best"
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/schemas/best",
"$ref": "https://example.com/schemas/better",
"type": "object",
"properties": {
"bestprop": {
"title": "the best property!",
"$ref": "base#/$defs/abc"
}
}
}
In base I've got $defs/abc
defined. I can reference it in both the other schemas as base#/$defs/abc
.
But what I'd like to do is somehow import its definition from base into better, so that in best I can reference it as better#/$defs/abc
instead of base#/$defs/abc
.
Is there a way to do this?
So far:
Using
#/$defs/abc
in best doesn't work; although I kind of actually expected it to, because I expected the top-level$ref
to pull everything in to each schema, including the$defs
object. (Similarily I noticed that#/$defs/abc
doesn't work from better, either, even though I expected it to given the top-level$ref
).I tried this in better:
"$defs": { "$ref": "base#/$defs" }
But then AJV (at least) complains that
$ref
is not an object/bool (since it's a string). I hand-wavily tried"base#/$defs/"
as well but that expectedly didn't work either.I also tried this in better, again hand-waving:
"$defs": { "allOf": [ { "$ref": "base#/$defs/" } ] }
But again AJV complained (since it's an array).
I don't really have any other ideas.
Why isn't the $defs
object being pulled in by the top-level $ref
(even though e.g. the properties
objects are being merged with no issue) and why isn't $ref
working inside $defs
? Is any of this possible? If so, how?
Also note that I say "import" but maybe there's some sort of "aliasing" type thing instead? My ultimate end goal is for all the things in base $defs
to appear as if they're actually in better, from the POV of best. -- without explicitly just copy pasting them from base to better, of course.
CodePudding user response:
You can use the $id
keyword to give your definitions a new name to use in references, so you don't have to keep track of whether it's defined in base or better:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/schemas/base",
"$defs": {
"abc": {
"$id": "https://example.com/schemas/abc",
"type": "string",
"pattern": "^[abcABC] $"
}
},
...
}
https://json-schema.org/understanding-json-schema/structuring.html