Are circular references between JSON Schemas (different files) allowed? - json

I have two JSON schemas that link each other:
schema.task.json and schema.dependency.json:
//file: schema.task.json
{
"$schema": "http://json-schema.org/draft-04/schema",
"type": "object",
"properties": {
"Dependencies": { "type": "array", "items": { "$ref": "schema.dependency.json#" } },
"TaskName": { "type": "string" }
}
}
//file: schema.dependency.json
{
"$schema": "http://json-schema.org/draft-04/schema",
"type": "object",
"properties": {
"StartAfterTask": { "$ref": "schema.task.json" },
"DependencyName": {"type": "string"}
}
}
When I try to edit json that use my Task schema, I see error in output window of visual studio:
Error loading schema ...\Visual Studio 2013\Projects\ConsoleApplication2\ConsoleApplication2\schema.dependency.json
Value cannot be null. Parameter name: uriString
If I'm doing circular reference within one file (in definitions section), it works fine.
I'm using Visual Studio 2013, Update 5, with schema http://json-schema.org/draft-04/schema
Does anyone know the right way to create JSON schemas with cross-files circular dependencies?

Yes, this is allowed - references between two different files are no different to reference within a file.
The syntax you've posted looks correct - have you tried raising an issue with the library you're using?

Related

MalformedURLException when using "$ref" in json schema

I have a json schema which refers to another json schema present in another folder using "$ref" (relative path) and i get a "MalformedURLException".
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$ref": "#/definitions/Base",
"definitions": {
"Base": {
"type": "object",
"additionalProperties": false,
"properties": {
"event": {
"$ref": "com/artifacts/click/ClickSchema.json"
},
"arrival_timestamp": {
"type": "integer",
"minimum": 0.0
}
},
"title": "Base"
}
}
}
And the click schema in another folder is as follows:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "com/artifacts/click/ClickSchema.json",
"Event": {
"type": "object",
"additionalProperties": false,
"properties": {
"sourceName": {
"type": "string"
}
}
}
}
Can someone please help. I am using this schema validator.
A JSON Schema knows nothing about where it sits in a file, and nothing about the other fils in a folder, by default.
It looks like the library you're using recognises this, and suggests you use a special reference protocol (classpath) to target other files in a folder with ease:
https://github.com/everit-org/json-schema#loading-from-the-classpath
As your schemas grow you will want to split that up into multiple
source files and wire them with "$ref" references. If you want to
store the schemas on the classpath (instead of eg. serving them
through HTTP) then the recommended way is to use the classpath:
protocol to make the schemas reference each other.
This isn't something defined by JSON Schema.
The more common approach is to load in all the schemas you intend to use, and allow for local resolution where you have the files already. The library you're using also supports this: https://github.com/everit-org/json-schema#registering-schemas-by-uri
Sometimes it is useful to work with preloaded schemas, to which we
assign an arbitary URI (maybe an uuid) instead of loading the schema
through a URL. This can be done by assigning the schemas to a URI with
the #registerSchemaByURI() method of the schema loader. Example:
SchemaLoader schemaLoader = SchemaLoader.builder()
.registerSchemaByURI(new URI("urn:uuid:a773c7a2-1a13-4f6a-a70d-694befe0ce63"), aJSONObject)
.registerSchemaByURI(new URI("http://example.org"), otherJSONObject)
.schemaJson(jsonSchema)
.resolutionScope("classpath://my/schemas/directory/")
.build();
There are additional considerations if you intend for your schemas to be used by others. If that's the case, do comment, and I'll expand.

Multiple schema JSON validation in Golang

I need to validate several JSON files against a schema in Golang.
I have been able to achieve it by using gojsonschema, that is really a straight forward library.
However, the problem I'm facing right now is that I have been given with schemas that have dependencies to another schemas and haven't found the way to load all the schemas that I need. Therefore, my validations always fail.
This is my main schema:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "#/definitions/List",
"definitions": {
"List": {
"type": "array",
"items": {
"$ref": "#/definitions/Item"
}
},
"Item": {
"description": "An item ....",
"type": "object",
"additionalProperties": false,
"properties": {
"property01": {
"description": "The property01 code.",
"$ref": "./CommonTypes.json#/definitions/Type01Definition"
}
},
"required": [
"property01"
]
}
}
}
And, I have another one with common types:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": {
"Type01Definition": {
"description": "The definition for the type 01",
"type": "string",
"pattern": "^[A-Z0-9]{3}$"
}
}
}
Is there a way to load several schemas using that library? Or is there any other Golang library that allows to achieve that?
The way to refer to a file using $ref is to specify the absolute path of the file using a URL scheme. If you change the $ref to look like "$ref" : "file:///home/user/directory/CommonTypes.json#/definitions/Type01Definition, your example will work as expected.
If you need a bit more flexibility you can either try gojsonschema's NewReferenceLoaderFilesystem or switch to a different Golang library https://github.com/santhosh-tekuri/jsonschema. That library allows you to add custom resources so you can load several schemas at once.

Reuse pattern in JSON schema

Is it possible to define a regex once and re-use it? I have a few pretty complex regexes which I would like to use as the pattern for the value of a large number of properties of various different object in my schema. Doing Copy paste of this looks like asking for trouble further down the line, but I can't seem to find a suitable re-use example anywhere.
Cut down schema which illustrates what I want to do.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"patterns": {
"fqdn_or_ipaddress": "(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{1,63}(?<!-)\\.)+[a-zA-Z]{2,63}$)||(((?:^[0-9])(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))(?![0-9])$)|(^\\*$))",
},
"properties": {
"server_hostname" : {
"type":"string",
"pattern": {"#ref", "#/patterns/address"},
},
"proxy_hostname" : {
"type":"string",
"pattern": {"#ref", "#/patterns/address"},
}
}
}
Doesn't validate here http://www.jsonschemavalidator.net/ because "pattern" is not a string. Is this a hole in the re-use. I've looked at patternProperties, but that seems to solve completely different use case.
You can only $ref a schema. You would need to do something like this.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"server_hostname" : {
"$ref": "#/definitions/fqdn_or_ipaddress",
"description": "The server hostname"
},
"proxy_hostname" : {
"allOf": [{ "$ref": "#/definitions/fqdn_or_ipaddress" }],
"description": "The proxy hostname"
}
},
"definitions": {
"fqdn_or_ipaddress": {
"type": "string",
"pattern": "(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{1,63}(?<!-)\\.)+[a-zA-Z]{2,63}$)||(((?:^[0-9])(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))(?![0-9])$)|(^\\*$))"
}
}
}
EDIT
I added two examples of how to extend from a $ref. In the first, you can just add the description. It will be ignored, but it is not an error. Since description is just a meta-data keyword, this shouldn't be a problem.
In the second example, you can use allOf to wrap the $ref and you can add whatever keywords you need (even non-meta data keywords).
This answer highlights key structure for reusing the defined pattern. However, the example does not validate as:
The definition is given as part of the object reference with "definitions" whereas the "$ref" path is referencing a "patterns" definition that is nowhere to be found.
The pattern definition key is provided as "fqdn_or_ipaddress" whereas the paths in the properties refer to a "fqn_or_ipaddress" which is not defined.
Following is the corrected sample that passes the validation in the JSON schema validator:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"server_hostname" : {
"$ref": "#/definitions/fqdn_or_ipaddress",
"description": "The server hostname"
},
"proxy_hostname" : {
"allOf": [{ "$ref": "#/definitions/fqdn_or_ipaddress" }],
"description": "The proxy hostname"
}
},
"definitions": {
"fqdn_or_ipaddress": {
"type": "string",
"fqdn_or_ipaddress": "(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{1,63}(?<!-)\\.)+[a-zA-Z]{2,63}$)||(((?:^[0-9])(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))(?![0-9])$)|(^\\*$))"
}
}
}

JSON Schema Dependencies remove key if another key present without using oneOf as it is not supported by alpacajs

I am using a alpacajs library to construct my json schema into a form that doesnt support oneOf keyword.
I have a simple requirement where if one field is present then the other one should be hidden.
Is there a way to implement using json schema itself without using oneOf keyword.
Right now i am using dependencies keyword to handle my conditions.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Company Setup",
"description": "Company Wizard Setup",
"type": "object",
"properties": {
"name": {
"type": "string",
"title": "Company Name"
},
"alternate_names": {
"type": "array",
"title": "Alternate Name",
"items": {
"type": "string"
},
"maxItems": 5
}
},
"dependencies": {
"name": "alternate_names"
}
}
{
"options": {
"fields": {
"name": {
"dependencies": {
"alternate_names": "Value for empty Array?"
}
},
"alternate_names": {
...
}
}
}
}
This is just a stripped down version of my schema for the sake of clarity and i would appreciate if anyone can help me tell if dependencies can be used to remove a field too. I could potentially just use javascript to get this but i wanted to handle this just using schema as i am going to use same for validation too, infact schema has more use as a validator than form itself.
Since none of the field is boolean, i can't just put true and false in value.
Thanks in advance.

Json schema relative $ref to current "id"

I have searched SO and JSON schema documentation for a few days now, but I'm struggling to get my JSON Schema references to work across multiple files in the same directory.
My root schema would be an oneOf object:
{
"$schema": "http://json-schema.org/draft-04/schema",
"id": "http://localhost/json-editor/schema/function.json",
"title": "Function",
"oneOf": [
{
"$ref": "./fn_md5.json"
},
{
"$ref": "fn_sha1.json"
}
]
}
Now after reading the docs and most questions here, I'd assume both ./fn_md5.json and fn_sha1.json would be resolved to http://localhost/json-editor/schema/fn_....json (where the ... represents their respective name, of course). However, the resolver keeps looking into http://localhost/json-editor/fn_....json, which appears to be relative to the application's url (JDorn's JSON Editor running at my http://localhost/json-editor/).
Am I understanding the schema and id wrong, or could it be an error with the editor's URL resolver?
Thanks!
for find the relative references you need use $id like this:
{
"$schema": "http://json-schema.org/draft-04/schema",
"id": "http://localhost/json-editor/schema/function.json",
"$id":"https://www.baseurl.com/"
"title": "Function",
"oneOf": [
{
"$id": "./fn_md5.json"
},
{
"$id": "fn_sha1.json"
}
]
}
source: https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-01#section-8.2.4