# Specification extensions

The OpenAPI spec allows for [extensions](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md#specification-extensions) to be defined that extend an API definition.
This document describes the custom extensions used in GitHub's REST API definition.
These exist for purposes like single-sourcing content to reduce duplication, presenting extra data in the documentation view, and generating Octokit API clients.

These specification extensions are used in GitHub's OpenAPI definition:
- [x-codeSamples](#x-codeSamples)
- [x-displayOptions](#x-displayOptions)
- [x-github](#x-github)
- [x-githubBreakingChanges](#x-githubBreakingChanges)
- [x-githubEnterpriseOverlays](#x-githubEnterpriseOverlays)
- [x-githubPlaceholders](#x-githubPlaceholders)

## `x-codeSamples`

### Purpose
Used for presenting [Octokit](http://github.com/octokit) API client code samples in the documentation.

### Usage
This `x-codeSamples` extension is defined within any [Operation object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md#operationObject).

The value should be a Code Sample Object.

| Field name  |	Type	   | Description  |
| :---------- | :------: | :----------- |
| lang        | string   | Code sample language. Value should be one of the following [list](https://github.com/github/linguist/blob/master/lib/linguist/popular.yml) |
| label       | string?   | Code sample label e.g. `octokit/rest` or `octokit.rb`, _optional_, `lang` will be used by default |
| source      | string   | Code sample source code |

#### Example usage

```yml
get:
    x-codeSamples:
    - lang: Shell
      source: |-
        curl \
            -H"Accept: application/vnd.github.v3+json" \
            ${apiURL}/user/subscriptions/octocat/hello-world
    - lang: JavaScript
      source: |-
        octokit.activity.checkWatchingRepoLegacy({
            owner: 'octocat',
            repo: 'hello-world'
        })
    - lang: Ruby
      source: |-
        octokit.check_watching_repo_legacy(
            'hello-world'
        )
```

## `x-displayName`

### Purpose

To define a display name, typically for documentation interfaces, for the corresponding tag.

### Usage

This applies to the [Tag Object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md#tagObject).

The value should be a string.

#### Example usage

```yml
tags:
  name: actions
  description: Endpoints to manage GitHub Actions using the REST API.
  x-displayName: GitHub Actions
```

## `x-github`

### Purpose

Provides extra information used to generate Octokit SDKs.

### Usage

The `x-github` specification extension is applied to the [Operation Object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md#operationObject).

| Field Name  |	Type	   | Description  |
| :---------- | :------: | :----------- |
| triggersNotification | boolean   | Operations that trigger notification are more likely to trigger abuse limits. We increase the default throttling from 1s between requests to 3s between requests for these operations. |
| legacy        | boolean   | Value should be true for [legacy operations](https://developer.github.com/v3/search/legacy/). These operations are omitted from the SDKs to discourage usage. |
| githubCloudOnly | boolean | Used in a [separate plugin](https://github.com/octokit/plugin-enterprise-cloud.js/) for GitHub Enterprise Cloud users. |
| enabledForApps       | boolean   | True if this operation is enabled for apps |
| previews      | array   | Previews will be deprecated soon. An array of API previews, with name, description, and whether the preview is required for this particular operation. |

<!--
Suggestion: rename legacy and enabledForApps to follow the convention suggested for boolean API properties (start with `is` or `has`).
-->

#### Example usage

```yml
x-github:
  legacy: false
  enabledForApps: true
  githubCloudOnly: false
  previews: []
```

## `x-githubBreakingChanges`

### Purpose

Keep a record of breaking changes.
The `x-githubBreakingChanges` (formerly known as `x-changes`) specification extension documents breaking changes to API parameters or operationIds for the purpose of SDK generation that handles breaking changes gracefully for clients.

### Usage

This applies to the [Operation Object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md#operationObject).

The `x-githubBreakingChanges` specification extension contains an array of objects.

| Field name  |	Type	   | Description  |
| :---------- | :------: | :----------- |
|type|string | The type is a required value and must be either `parameter` or `operation`. When the breaking change applies to an operationId, use `operation`. When the breaking change applies to parameters or body properties, use `parameter`.|
|date|string (date)|The date is a required value and must be in ISO-8601 format (eg. 2020-05-23).|
|note|string|A brief description of the change.|
|before|[Change object](#change-object)|Describes the version before the breaking change. (required)|
|after|[Change object](#change-object)|Describes the version before the breaking change. (required)|

The change object is used to describe the before and after version of the breaking changes.
This enables the SDK to map them.

##### Change object

| Field name  |	Type	   | Description  |
| :---------- | :------: | :----------- |
| description | string | The description of the property at that particular before or after version.|
| name | string | The name of the parameter or property (only applies to type `parameter`).|
| in | string | Specifies in the path or body (applies to type `parameter`) |
| type | string | Specifies the data type of the `parameter`). |
| operationId | string | The `operationId` (applies to type `operation`).|


#### Example usage

```yml
x-githubBreakingChanges:
  - type: parameter
    date: '2019-04-10'
    note: '"number" parameter renamed to "pull_number"'
    before:
      name: number
    after:
      name: pull_number
  - type: operation
    date: '2019-09-09'
    note: >-
      "Create a comment reply" is now "Create a comment". To create a pull request review comment reply, use the new
      "Create a review comment reply" endpoint
    before:
      operationId: pulls/create-comment-reply
    after:
      operationId: pulls/create-comment
  - type: parameter
    date: '2019-09-09'
    note: >-
      "in_reply_to" parameter is deprecated for "Create a comment". To create a pull request review comment reply, use
      the new "Create a review comment reply" endpoint
    before:
      name: in_reply_to
      description: >-
        The comment ID to reply to. **Note**: This must be the ID of a top-level comment, not a reply to that comment.
        Replies to replies are not supported.
      in: body
      type: integer
    after: {}
```

## `x-githubEnterpriseOverlays`

### Purpose
This is used by the OpenAPI-cli transformer [OverlaysMerger.js](./scripts/transformers/OverlaysMerger.js).
This transformer modifies the Enterprise schemas based on the public API definition.

The overlay is [merged](https://tools.ietf.org/html/rfc7386) into the contained object for the version(s) defined in the key.

### Usage

This is applied to the [Operation Object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md#operationObject).

The `x-githubEnterpriseOverlays` should contain a property with the [semantic version range](https://docs.npmjs.com/misc/semver#ranges) reference to the Enterprise version.
It behaves like a key matched by the overlay transformer.

##### Examples semver ranges

- `*` (any Enterprise version)
- `2.20` (only Enterprise version 2.20)
- `2.17 - 2.19` (Enterprise versions 2.17, 2.18, 2.19)
- `>=2.17` (All versions greater than or including 2.17)

[Semver cheatsheet](https://devhints.io/semver)

The value for each key should contain the parts of the operation that should overlay on top of the Operation Object it belongs to using [JSON merge](https://tools.ietf.org/html/rfc7386).


#### Example usage

```yml
x-githubEnterpriseOverlays:
  '2.19':
    parameters:
      - $ref: ../../components/parameters/accept.yml
      - $ref: ../../components/parameters/team_id.yml
      - $ref: ../../components/parameters/discussion_number.yml
      - $ref: ../../components/parameters/comment_number.yml
    x-github:
      previews:
        - name: squirrel-girl
          note: >-
            The [reactions API](${externalDocsUrl}/v3/reactions/) is available for developers to preview. The `url` can
            be used to construct the API location for [listing and creating](${externalDocsUrl}/v3/reactions) reactions.
            See the [blog post](https://developer.github.com/changes/2016-05-12-reactions-api-preview) for full details.
            To receive the `reactions` object in the response for this endpoint you must provide a custom [media
            type](${externalDocsUrl}/v3/media) in the `Accept` header:

            ```
            application/vnd.github.squirrel-girl-preview
            ```
          required: false
  '2.20':
    parameters:
      - $ref: ../../components/parameters/accept.yml
      - $ref: ../../components/parameters/team_id.yml
      - $ref: ../../components/parameters/discussion_number.yml
      - $ref: ../../components/parameters/comment_number.yml
    x-github:
      previews:
        - name: squirrel-girl
          note: >-
            The [reactions API](${externalDocsUrl}/v3/reactions/) is available for developers to preview. The `url` can
            be used to construct the API location for [listing and creating](${externalDocsUrl}/v3/reactions) reactions.
            See the [blog post](https://developer.github.com/changes/2016-05-12-reactions-api-preview) for full details.
            To receive the `reactions` object in the response for this endpoint you must provide a custom [media
            type](${externalDocsUrl}/v3/media) in the `Accept` header:

            ```
            application/vnd.github.squirrel-girl-preview
            ```
          required: false
```

## `x-githubPlaceholders`

### Purpose

This is used by the OpenAPI-cli transformer [PlaceholderReplacer.js](./scripts/transformers/PlaceholderReplacer.js).
This allows for using strings specific to an OpenAPI root document deeper within shared schema.

### Usage

The placeholders are set at the root-level (top-most section) of the OpenAPI definition.

| Field Name  |	Type	   | Description  |
| :---------- | :------: | :----------- |
| externalDocsUrl        | url   | Value should be a fully qualified URL. |
| apiName       | string   | The name of the API. |
| version      | string   | The string that represents the version. |

Then, subsequently use the placeholders within the definition like `${externalDocsUrl}`, `${apiName}`, or `${version}`.

Note: `${version}` is only used by the [import.js](./scripts/import.js) script.
It may be removed after the [import script is removed](https://github.com/github/openapi/issues/23).

#### Adding a new placeholder

Add a key and value to the `x-githubPlaceholders` object.
Then, use it with the syntax of `${key}` within the definition for later replacement by the transformer.
The transformer runs as part of the openapi-cli bundle command.

#### Example usage

```yml
x-githubPlaceholders:
  externalDocsUrl: 'https://developer.github.com'
  apiName: GitHub
  version: api.github.com
```

```yml
x-githubPlaceholders:
  externalDocsUrl: 'https://developer.github.com/enterprise/2.19'
  apiName: GitHub Enterprise Server
  version: ghe-2.19
```

Then, used within the definition.

```yml
externalDocs:
  description: API method documentation
  url: '${externalDocsUrl}/v3/issues/assignees/#remove-assignees-from-an-issue'
```

## Adding new specification extensions

Follow this checklist when adding a new specification extensions:
- [ ] Update this documentation.
- [ ] Create a custom rule to validate the specification extension values.

<!-- TODO: add more information about creating a custom rule -->

## Deprecated specification extensions

### `x-github-docs-category`

Use [`x-displayName`](#x-displayName) instead.

### `x-code-samples`

Use [`x-codeSamples`](#x-codeSamples) instead.
