The id keyword - sgpinkus/json-schema GitHub Wiki

THIS WIKI IS OBSOLETE. PLEASE SEE THE NEW JSON-SCHEMA-ORG/JSON-SCHEMA-SPEC REPOSITORY.



Foreword

The current draft has this to say with regards to id:

5.27.  id

   This attribute defines the current URI of this schema (this attribute
   is effectively a "self" link).  This URI MAY be relative or absolute.
   If the URI is relative it is resolved against the current URI of the
   parent schema it is contained in.  If this schema is not contained in
   any parent schema, the current URI of the parent schema is held to be
   the URI under which this schema was addressed.  If id is missing, the
   current URI of a schema is defined to be that of the parent schema.
   The current URI of the schema is also used to construct relative
   references such as for $ref.

Unfortunately, this leaves a lot of ground for confusion and possibilities for malformed, or nonsensical, IDs.

This page will start by describing an unambiguous id scheme, followed by examples of not what to do -- and why.

Example scheme to define an unambiguous set of identifiers

The parent schema id: absolute, or none

This is an example of an id which is fully addressable by a JSON Reference:

{
    "id": "http://some.site/my/schema.json"
}

If you load this schema from JSON directly, this ID should be considered the schema's URI. From any other schema you will potentially use, you will be able to address this schema, or parts of it (see below), using this URI as a base.

If, however, you have loaded this schema from a URI which is not the one in id, while the spec doesn't really say so, you should probably consider that this URI is the schema's URI and not the one in id: chances are other schemas will use the URI you used yourself to download the schema -- and chances are equally non zero that the URI in id is stale anyway.

Subschema ids: anchors

Example:

{
    "description": "main schema",
    "id": "an://absolute/uri/here.json",
    "subschema1": {
        "id": "card"
    },
    "subschema2": {
        "id": "person"
    }
}

This means you will be able to address, for instance, the person schema using:

{
    "$ref": "an://absolute/uri/here.json#person"
}

Note about parent schemas without an id

If you load a JSON schema from JSON directly and it has no id, then this schema is, effectively, rootless. Its base URI is empty.

Some implementations choose to generate a URI for such schemas (more often than not a URN). That is all good and fine, but unneeded: this schema will, in any case, not be addressable from any other schema.

Examples of what not to do

A parent's schema id which is not absolute

It just makes no sense at all. First, because you will not be able to use this id to address this schema from outside of itself. Second, because you can always refer to the parent schema as # from within any subschema, no need to define an anchor. For instance:

{
    "description": "DON'T DO THAT",
    "id": "a/schema.json",
    "schema": {
        "description": "you want to go here"
    }
}

This id can never be addressed.

A subschema id which is an absolute URI

Same reason as above: it will never be addressable.

Subschema ids starting with /

You MUST NOT do that for a simple reason: JSON References, when a URI fragment starts with a /, should treat that fragment as a JSON Pointer. Which means, in this scenario:

{
    "schema1": { "id": "/main" },
    "main": {}
}

JSON Reference #/main will find subschema main and not schema1.

⚠️ **GitHub.com Fallback** ⚠️