# References ($ref) in OpenAPI
Source: https://speakeasy.com/openapi/references

import { Table } from "@/mdx/components";



While creating an OpenAPI schema, you might notice duplicated parts in your document. Using references in OpenAPI helps you define a schema once and reuse it elsewhere in the document. This approach minimizes duplication and makes your OpenAPI document more readable and maintainable.

To reference a schema, use the `$ref` keyword followed by the path to the schema. The path can be an absolute or relative URI and can also refer to objects in different files.

## OpenAPI Reference Object

Any object supported by the [Components Object](/openapi/components) can be replaced by an OpenAPI Reference Object. A Reference Object points to a component using the `$ref` field, which is itself a [JSON Schema Reference](#json-schema-references) and can optionally override the `summary` or `description` of the referenced object.

<Table
  data={[
    { field: "`$ref`", type: "String", required: "✅", description: "A [JSON Schema reference](#json-schema-references) to a component." },
    { field: "`summary`", type: "String", required: "", description: "A summary that overrides the referenced component's `summary` field. This field is ignored if the referenced component's type does not support the `summary` field." },
    { field: "`description`", type: "String", required: "", description: "A detailed description that overrides the referenced component's `description` field. This field is ignored if the referenced component's type does not support the `description` field. This may contain [CommonMark syntax](https://spec.commonmark.org/) to provide a rich description." }
  ]}
  columns={[
    { key: "field", header: "Field" },
    { key: "type", header: "Type" },
    { key: "required", header: "Required" },
    { key: "description", header: "Description" }
  ]}
/>

In the example below, we define a `Drink` schema in the `components` section:

```yaml  filename="openapi.yaml" mark=3:11
components:
  schemas:
    Drink:
      type: object
      summary: A drink in the bar
      description: A drink that can be ordered in the bar
      properties:
        name:
          type: string
        recipe:
          type: string
```

We can reference this component in API paths using a Reference Object:

```yaml filename="openapi.yaml" mark=10:11
paths:
  /drinks:
    post:
      summary: Create a new drink
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Drink" # References the Drink schema
              summary: A drink to add to the bar # Overrides the Drink schema summary
      responses:
        "200":
          description: OK
```

In this example, the `Drink` schema is referenced in the `requestBody` of the `POST /drinks` operation. The `summary` field in the Reference Object overrides the `summary` field of the `Drink` schema.

## JSON Schema References in OpenAPI

OpenAPI inherits the flexible JSON Schema `$ref` keyword. A JSON Schema reference is an absolute or relative URI that points to a property in the current schema or an external schema. Relative references are resolved using the current document's location as the base URI. Paths inside `$ref` use JSON Pointer syntax (JSON Pointer is different from JSONPath, which is not part of JSON Schema).

The JSON Schema `$ref` can reference elements within the same schema or external schemas, or the path defined inside an object's `$id` field. By contrast, OpenAPI Reference Objects are focused on referencing components defined within the `components` section of an OpenAPI document and allow for overriding the `summary` and `description` metadata of the referenced component.

The `$id` field in JSON Schema provides a unique identifier for a schema that `$ref` can reference. The `$id` field must be a URI.

Most objects in a schema are themselves valid schemas and can thus have an `$id` field. Note that `$id`, not `id`, is a keyword in JSON schema and should be used for references.

## JSON Schema Reference Escape Characters

The `/` character separates segments in a JSON Pointer, for instance, `$ref: "#/components/schemas/Drink"`.

To refer to a property that contains the `/` character in its name, escape `/` in the `$ref` using `~1`. Since `~` is the escape character in paths, `~` must be escaped as `~0`.

For example, consider the JSON object below:

```json filename="example.json"
{"a/b": { "c~d": "value" }}
```

To create a pointer to `value`, you would need to use the string `/a~1b/c~0d`.

## Types of References in OpenAPI

References in OpenAPI can be relative or absolute. Relative references point to elements within the same API description, while absolute references point to elements in external documents. Absolute references can also point to external resources like online JSON files. Runtime expressions are another type of reference that allows for dynamic values during API execution.

<Table
  data={[
    { refString: "`#/components/schemas/Drink`", description: "References the `Drink` schema in the `components` section of the current file." },
    { refString: "`./person.yaml`", description: "References the entire `person.yaml` file. The entire content of `person.yaml` is used." },
    { refString: "`../person.yaml`", description: "References the `person.yaml` file in the parent directory. The entire content of `person.yaml` is used." },
    { refString: "`./people.yaml#/Person`", description: "References the `Person` schema in the `people.yaml` file. Only the `Person` schema from `people.yaml` is used." },
    { refString: "`https://pastebin.com/raw/LAvtwJn6`", description: "References an external schema stored online. The entire content of the external schema is used." },
    { refString: "`$request.path.orderId`", description: "A runtime expression that passes the `orderId` from the parent operation." }
  ]}
  columns={[
    { key: "refString", header: "`$ref` string" },
    { key: "description", header: "Description" }
  ]}
/>


### Relative References in OpenAPI

Relative references specify a location based on the current document and are useful for referencing elements within the same API description.

In the example below, the reference points to the `Drink` schema defined within the `components` section of the current OpenAPI document:

```yaml filename="openapi.yaml" mark=9
paths:
  /order:
    post:
      summary: Place an order for a drink
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Drink" # Relative reference to the Drink schema
```

### Absolute References in OpenAPI

Absolute references include a protocol like `http://` or `https://` followed by the rest of the URI.

The example below references an `Ingredient` component in a remote OpenAPI document:

```yaml filename="openapi.yaml" mark=13:14
paths:
  /drinks:
    get:
      summary: Get ingredients
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  # Absolute reference to an external schema
                  $ref: "https://speakeasy.bar/schemas/ingredients.yaml#/components/schemas/Ingredient"
```

### Runtime Expressions in OpenAPI

Runtime expressions allow for dynamically determining values during API execution. These expressions add flexibility and reduce the need for hard coding details in an API description.

Expressions in OpenAPI always begin with the dollar sign `$` and indicate the string that follows must be calculated from the HTTP request or response. To embed an expression in another string, wrap it in `{}`.

Runtime expressions are commonly used in [Link Objects](/openapi/responses/links) and [Callbacks Objects](/openapi/webhooks/callbacks#callback-object-in-openapi) to pass dynamic values to linked operations or callbacks. An example is:

```yaml filename="openapi.yaml" mark=9
paths:
  /orders/{orderId}:
    get:
      # ...
    links:
      viewItems:
        operationId: getOrderItems
        parameters:
          orderId: $request.path.orderId # Pass orderId from the parent operation
```

## Additional Syntax

The following sections show some more advanced ways of using references to structure an API neatly.

As the basis of the examples to follow, the following `openapi.yaml` describes a single operation that takes a person's ID and returns their name:

```yaml filename="openapi.yaml" mark=5:25
openapi: 3.1.0
info:
  title: Person API
  version: 1.0.0
paths:
  /persons/{id}:
    get:
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                  name:
                    type: string
```

### Local File References

The definition of the type that is returned can be moved into its own file so that other operations or other files can use it, too. The operation's `responses` object in `openapi.yaml` now has a `$ref` field:

```yaml filename="openapi.yaml" mark=7
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: 'person.yaml' # Reference to the person schema in a separate file
```

In this example, the `$ref` uses a relative path that points to the entire `person.yaml` file in the same folder with the following content:

```yaml filename="person.yaml"
type: object
properties:
  id:
    type: string
  name:
    type: string
```

### Online File References in OpenAPI

Schemas can be stored online, for example, in [Pastebin](https://pastebin.com). The reference in `openapi.yaml` can refer to the online `Person` definition:

```yaml filename="openapi.yaml" mark=7
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: "https://pastebin.com/raw/LAvtwJn6"
```

The content of the `Person` schema is stored in the Pastebin link `https://pastebin.com/raw/LAvtwJn6`:

```yaml filename="https://pastebin.com/raw/LAvtwJn6"
type: object
properties:
  id:
    type: string
  name:
    type: string
```

### Organize Schemas and Components in Files in OpenAPI

While it is common practice to define an OpenAPI document's schemas and components in a single file, a schema _may_ be split across multiple files using references.

In a JSON schema file containing multiple objects, the `Person` object might look like this:

```yaml filename="people.yaml" mark=1:7
Person:
  type: object
  properties:
    id:
      type: string
    name:
      type: string

Employee:
  ...

Student:
  ...
```

The `openapi.yaml` OpenAPI document can reference the `Person` schema from `people.yaml` using the filename and path:

```yaml filename="openapi.yaml" mark=7
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: "people.yaml#/Person"
```

### Nested References in OpenAPI

References can be nested so that a schema can reference another schema that references a third schema. In the example below, the `Person` schema references the `Address` schema, which in turn references the `Country` schema:

```yaml filename="openapi.yaml" mark=11,20
components:
  schemas:
    Person:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        address:
          $ref: "#/components/schemas/Address"
    Address:
      type: object
      properties:
        street:
          type: string
        city:
          type: string
        country:
          $ref: "#/components/schemas/Country"
    Country:
      type: string
```

### Circular References in OpenAPI

Circular references are valid in OpenAPI and useful to define recursive objects. In the example below, the `Person` component is redefined to have an array of children, with each child a circular reference to `Person`.

```yaml filename="openapi.yaml" mark=10:13
components:
  schemas:
    Person:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        children:
          type: array
          items:
            $ref: '#/components/schemas/Person'
```

Although tooling may pass a schema as syntactically valid, it could still be logically unusable. For example, code generation tools that generate SDKs or example requests and responses will fail when used on the schema below that has an infinitely recursive reference:

```yaml filename="infinite-recursion.yaml"
components:
  schemas:
    Person:
      $ref: '#/components/schemas/Human'
    Human:
      $ref: '#/components/schemas/Person'
```

### Composition in OpenAPI

The `$ref` keyword can be used to compose schemas of multiple objects.

Using composition in schemas is described in [`allOf`, `anyOf`, and `oneOf`](/openapi/schemas/objects/polymorphism).

The `$ref` keywords used in the examples in that explanation could be external file references instead of component references.

### Arrays and Objects in OpenAPI

The `$ref` keyword can be used to replace an entire array or individual items in the array.

However, some fields in an OpenAPI schema require each array item or object property to be referenced individually and the entire field may not be replaced with one `$ref`. The fields that must list each item separately are `servers`, `tags`, `paths`, `security`, `securitySchemes/scopes`, and `components`.

## Object Type Examples in OpenAPI

This section gives examples for all the places `$ref` can be used.

Objects referenced can be in a `components` section of the schema or a separate file. The first example below shows both options, the rest of the examples illustrate referencing objects in the `components` section only.

### Referencing Parameters in OpenAPI

The parameters for the operation `listDrinks`:

```yaml filename="openapi.yaml"
      parameters:
        - name: type
          in: query
          description: The type of drink to filter by. If not provided all drinks will be returned.
          required: false
          schema:
            $ref: "#/components/schemas/DrinkType"
```

The same schema with a reference to the `components` section:

```yaml filename="openapi.yaml"
      parameters:
        - $ref: '#/components/parameters/DrinkTypeParameter'