29

I'm trying to refer to a JSON schema located in a different file using "$ref" with Liquid Studio 2017. Both the referring JSON schema and the referred JSON schema are located within the same directory.

I tried it using relative paths:

"$ref": "referredSchema.json/propertyName"

and using absolute paths:

"$ref": "file:///C:/JSON/referredSchema.json/propertyName"
"$ref": "file:///JSON/referredSchema.json/propertyName"
"$ref": "file:///JSON/referredSchema.json#/propertyName"

and a few other variations. None of them worked, I always get an error message "Invalid URI". Also the documentation only mentions that refs to other documents are possible without giving a reasonable example.

So I wonder, what the expected URI format would be.

SOFe
  • 7,867
  • 4
  • 33
  • 61
hounce
  • 312
  • 1
  • 3
  • 6

1 Answers1

32

You can reference schemas defined in the local file or external files using the $ref property.

The issue you have is the fragment part (the bit after the #). This references a schema within the definitions property on the root schema.

The following example should show how to do this for local files and external files

Main.json

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "type": "object",
    "additionalProperties": false,
    "properties": {
        "ReferenceToLocalSchema": {
            "$ref": "#/definitions/LocalType"
        },
        "ReferenceToExternalSchema": {
            "$ref": "Common.json#/definitions/ExternalType"
        }
    },
    "definitions": {
        "LocalType": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
                "no-write": {
                    "type": "boolean",
                    "default": false
                }
            }
        }
    }
}

JSON Schema Diagram

Common.json

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "type": "object",
    "additionalProperties": false,
    "definitions": {
        "ExternalType": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
                "src": {
                    "type": "array",
                    "items": {
                        "type": "string",
                        "minLength": 1
                    }
                }
            },
            "required": [
                "src"
            ]
        }
    }
}

JSON Schema Diagram

Notice the reference to the local schema

"$ref": "#/definitions/LocalType"

and the remote schema

"$ref": "Common.json#/definitions/ExternalType"

I've shown this with a relative url, but it could be a fully qualified url

"$ref": "file:///Common.json#/definitions/ExternalType"

One thing to note. At the moment the list of possible options presented in the UI will only show the definitions that are defined in the local file. References to external files will have to be entered in the code view.

enter image description here

If you still have questions please add the schema to the question.

Sprotty
  • 5,676
  • 3
  • 33
  • 52
  • Hi Sprotty - for the sake of understanding the case: If the Common.json in the main node would be decorated with "$id" : "#Common" could I refer in Main.json via "ReferenceToExternalSchema": { "$ref": "Common.json#Common" } (assuming it makes sense for me for some reason) ? – PsychoFish Oct 31 '18 at 14:28
  • 1
    The resolution rules when you start setting the 'id' property ($id in v6) are VERY complex and inconsistently implemented by JSON Schema tools. The following gives a taste of what the id property does. https://stackoverflow.com/questions/46671285/id-property-usage-in-json-schema – Sprotty Nov 14 '18 at 09:52
  • Thanx @Sprotty. I am working on rather large schemas with lots of relative referencing, they're structurized so it is easy to split them into multiple files, yet in the meantime I figured it all depends on your exact tool/lib one uses. ANd yes, indeed, JSON pointers can create a hell of a headache (exactly as in referenced examples) ;-) – PsychoFish Nov 14 '18 at 13:50
  • If I want to reuse a structure in multiple declarations, but in some cases I want one field to be mandatory and in other cases not, is it possible ? Other way said, how can I make mandatory a field that is included in the referenced object ? – Victor Nov 10 '20 at 12:33
  • 1
    @Victor you can do this using an allOf, add the $ref and a second schema, the second schema just needs to say that field x is required. – Sprotty Nov 10 '20 at 13:27
  • Thx! I also found this link that is explaining what you said: https://stackoverflow.com/questions/57198531/apply-required-field-to-referenced-json-data-schema – Victor Nov 10 '20 at 14:06