Last updated 11 months ago

Using JSON references ($refs)

OpenAPI 3 allows for using JSON Reference objects.

JSON References are required to accomplish:

  • a multi-file structure
  • re-use of schemas or other content

Reference structure

$ref key

The JSON Reference uses a $ref key.

yamljson
$ref: <reference>
"$ref": "<reference>"

Reference value

The value of the <reference> is a JSON Reference which is composed of two parts <relative path to file or URL><JSON pointer>.

File reference

Possible values:

  • empty (to refer to the current document)
  • path (relative to the current file)
  • URL (including the protocol)

Pointer

Possible values:

  • empty (to refer to the entire file -- this is the same as #).
  • # with path to the object (refers to the root of the document). Each path segment should have a / preceding it (eg. #/foo).

Here is an example document.

foo: true
bar:
  fee:
    color: purple
    taste: great

To refer to the fee object within the same file we would use #/bar/fee:

$ref: '#/bar/fee'

References by example

There are 5 varieties of references examples:

  1. Reference a definition within the same file by a pointer within the file.
  2. Reference a separate file by a relative path.
  3. Reference a definition within a separate file by a relative path to the file and pointer to the object.
  4. Reference a file by remote URL.
  5. Reference a definition within a file by remote URL and pointer to the object.

Definition within same file

Use a JSON Pointer to the object.

yamljson
    schema:
      $ref: '#/components/schemas/Pet'
{
    "schema": {
        "$ref": "#/components/schemas/Pet"
    }
}

Definition is a separate file

    schema:
      $ref: './components/schemas/Pet.yaml'

Definition within a separate file

Within a separate file we need a relative path to the file and then the JSON Pointer path to the object separated by a # mark.

    schema:
      $ref: './components/schemas.yaml#/Pet'

Definition is a file at a remote URL

    schema:
      $ref: 'https://example.com/components/schemas/pet.yaml'

Definition is within a file at a remote URL

    schema:
      $ref: 'https://example.com/components/schemas.yaml#/Pet'

Common mistakes

No siblings

The OpenAPI Specification says:

This object cannot be extended with additional properties and any properties added SHALL be ignored.

In this example, we're trying to re-use the Skill object, but we wish to change the example skill to super-sniffer.

Trying to extend the object with a sibling is not valid:

# invalid example (common mistake)
    skill:
      $ref: '#/components/schemas/Skill'
      example: super-sniffer

Do this instead:

    skill:
      allOf:
        - $ref: '#/components/schemas/Skill'
        - example: super-sniffer

Wrong path to $ref

The path is evaluated from the file itself. Using paths relative to the root file is a common mistake.

Using references on disallowed properties

To be strictly compliant with OpenAPI 3, a JSON Reference can only be used where explicitly noted in the OpenAPI specification. For example, it can be used for Paths, Parameters, Schema Objects, and more:

Alternatively, any time a Schema Object can be used, a Reference Object can be used in its place. This allows referencing definitions instead of defining them inline.

In addition, Redocly widely supports a non-compliant JSON Reference of the info object's description property for the purpose of embedded markdown.

Incorrect examples by reference

We commonly see incorrect examples usage by reference objects. The OpenAPI specification allows for the examples to have a map of example or reference objects. The reference object must comply to the example object structure. Typically, we see the example containing only the value of the example; however, it must contain an object with a key labeled value and the value should appear there.

Common mistake

Excerpt of openapi.yaml root document with the reference on a disallowed property.

examples:
  fluffy:
    value:
      $ref: ./fluffy.yaml

The fluffy.yaml file with incorrect content structure.

petType: dog
name: fluffy

Correct structure

Excerpt of openapi.yaml root document with the reference in the correct location.

examples:
  fluffy:
    $ref: ./fluffy.yaml

The fluffy.yaml file contents with the correct example object schema.

value:
  petType: dog
  name: fluffy

Further reading

Read the IETF papers about these topics: