How to correctly reference other JSON Schema Documents ($ref)

4.4k Views Asked by At

I've read through the RFCs regarding JSON Schema and JSON pointers, but I'm still struggling to understand how to correctly reference other documents.

Lets say I have the following files (on disk):

/foo/bar/schema/base.json
/foo/bar/schema/model/model.json

The base.json like this:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "id": "/schema/base",
  "title": "Base Response",
  "description": "Schema descriptions of common properties of a response",
  "type": [ "object" ],

  "definitions": {
    "data": {
      "descrpition": "The response data is encapsulated within here",
      "example": "true",
      "type": [ "object", "array", "boolean", "null" ]
    }
  },

  "properties": {
    "data": { "$ref" : "#/definitions/data" }
  }
}

The model.json file is something like this:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "id": "/schema/model/model",
  "type": "object",

  "$ref": "/schema/base.json"
}

The $ref value in the model.json is what I am asking about. My understanding of the standard was that between the id and $ref of the document, we should be able to find the document.

Alternatively, I wondered whether something like:

"$ref": "../../base.json"

Would work?

But neither of those solutions seem to work using either Python or PHP libraries I've tried. I'm not sure where I'm going wrong?

1

There are 1 best solutions below

1
On BEST ANSWER

First of all, different libraries tackle $ref resolution in different ways, so you will need to follow their specific documentation to figure out the exact details. But below is some general information about $ref resolution that you might find helpful.

Think of your schema document as webpage you are viewing in a browser. The id represents the URL in your browser's URL bar. It must be a full absolute normalized URL, just like in your browser.

{
  "id": "file:///path/to/project/foo/bar/schema/model/model.json"
}

Think of $ref like a link in the webpage you are viewing in the browser. In can be absolute or relative, just like in your browser. A relative $ref will resolve following the same rules as a link on a webpage. For example, I would expect all $refs in the following JSON to resolve to the same value. (Note: it is not valid to use more than one $ref. This is just for illustration.)

{
  "id": "file:///path/to/project/foo/bar/schema/model/model.json",
  "$ref": "file:///path/to/project/foo/bar/schema/base.json",
  "$ref": "/path/to/project/foo/bar/schema/base.json",
  "$ref": "../model.json"
}

If id is not present, the URI used to retrieve the schema should be assumed to be the id. In this case file:///path/to/project/foo/bar/schema/model/model.json.

That's how it's supposed to work from a high level, but implementations vary in how they implement this. Some require the library to be setup in particular way. For example, a PHP validator I've used requires you to register all your schemas into a SchemaStore before they can be referenced.

Reference: http://json-schema.org/latest/json-schema-core.html#anchor27