OpenAPI Overlays
Overlays allow us to modify an existing OpenAPI document without directly editing the original document. An overlay is a separate document that contains instructions for updating the original OpenAPI document.
Active Development
The OpenAPI Overlay Specification (opens in a new tab) is still under active development, and is therefore not considered stable. However, it is supported by Speakeasy and many other tools in the OpenAPI ecosystem.
Overlays are useful for:
- Separating concerns between the original API definition and modifications required by different consumers or use cases.
- Avoiding direct modification of the original OpenAPI document, which may be managed by a separate team or process.
- Applying a set of common modifications to multiple OpenAPI documents.
Overlay Document Structure in OpenAPI
An Overlay document is a separate document from the OpenAPI document it modifies. It contains an ordered list of Action Objects that describe the modifications to be made to the original OpenAPI document.
Field Name | Type | Required |
---|---|---|
overlay | String | ✅ |
The version of the Overlay Specification that the document uses. The value must be a supported version number
Field Name | Type | Required |
---|---|---|
title | String | ✅ |
A human-readable title describing the purpose of the Overlay document.
Field Name | Type | Required |
---|---|---|
version | String | ✅ |
A version identifier indicating the version of the Overlay document.
Field Name | Type | Required |
---|---|---|
actions | [Action Object] | ✅ |
An ordered list of Action Objects to be applied to the original OpenAPI document. The list must contain at least one Action Object.
Field Name | Type | Required |
---|---|---|
version | String | ✅ |
A JSONPath (opens in a new tab) expression that specifies the location in the original OpenAPI document where the change should be made. See Action Targets.
Field Name | Type | Required |
---|---|---|
version | String |
A description of the action. This may contain CommonMark syntax (opens in a new tab) to provide a rich description.
Field Name | Type | Required |
---|---|---|
version | String |
An object containing the properties and values to be merged with the objects referenced by the target
. This field has no effect if the remove
field is true
.
Field Name | Type | Required |
---|---|---|
version | String |
If true
, the objects referenced by the target
are removed from the original document. If false
or not provided, the objects are not removed. This field takes precedence over the update
field.
overlay: 1.0.0info:title: Overlay to fix the Speakeasy barversion: 0.0.1actions:- target: "$.tags"description: Add a Snacks tag to the global tags listupdate:- name: Snacksdescription: All methods related to serving snacks- target: "$.paths['/dinner']"description: Remove all paths related to serving dinnerremove: true
Field Name | Type | Required | Description |
---|---|---|---|
overlay | String | ✅ | The version of the Overlay Specification that the document uses. The value must be a supported version number. |
info | Info Object | ✅ | Provides metadata about the Overlay document. |
extends | String | A URL to the original OpenAPI document this overlay applies to. | |
actions | [Action Object] | ✅ | An ordered list of Action Objects to be applied to the original OpenAPI document. The list must contain at least one Action Object. |
x-* | Extensions | Any number of extension fields can be added to the Overlay document that can be used by tooling and vendors. When provided at this level, the extensions generally apply to the entire document. |
The extends
field is optional. If not provided, it is the responsibility of tooling to determine which OpenAPI documents the overlay should be applied to.
Overlay Specification Versions
The overlay
field contains the version number of the Overlay Specification that the document conforms to. Tooling should use this value to interpret the document correctly.
The current version of the Overlay Specification is 1.0.0
, but keep in mind that the specification is still under development.
Overlay Info Object in OpenAPI
Provides metadata about the Overlay document.
Field Name | Type | Required | Description |
---|---|---|---|
title | String | ✅ | A human-readable title describing the purpose of the Overlay document. |
version | String | ✅ | A version identifier indicating the version of the Overlay document. |
x-* | Any | Any number of extension fields can be added that can be used by tooling and vendors. |
Action Object in OpenAPI
Each Action Object represents at least one change to be made to the original OpenAPI document at the location specified by the target
field.
Field Name | Type | Required | Description |
---|---|---|---|
target | String | ✅ | A JSONPath (opens in a new tab) expression that specifies the location in the original OpenAPI document where the change should be made. See Action Targets. |
description | String | A description of the action. This may contain CommonMark syntax (opens in a new tab) to provide a rich description. | |
update | Any | An object containing the properties and values to be merged with the objects referenced by the target . This field has no effect if the remove field is true . | |
remove | Boolean | If true , the objects referenced by the target are removed from the original document. If false or not provided, the objects are not removed. This field takes precedence over the update field. | |
x-* | Any | Any number of extension fields can be added to the Action Object that can be used by tooling and vendors. |
Action Targets in OpenAPI
The target
field of an Action Object is a JSONPath (opens in a new tab) expression that specifies the locations in the original OpenAPI document where the change should be made.
JSONPath expressions allow you to select and manipulate specific parts of a JSON or YAML document using an intuitive syntax. The expressions are similar to XPath for XML, allowing you to traverse the document tree and select elements based on various criteria.
JSONPath is implemented differently (opens in a new tab) across tooling languages and among individual tools. Speakeasy uses VMware Labs YAML JSONPath (opens in a new tab) to parse JSONPath.
Here are some examples of JSONPath expressions relevant to OpenAPI documents:
JSONPath Expression | Description |
---|---|
$.info.title | Selects the title field of the info object. |
$.servers[0].url | Selects the url field of the first server in the servers array. |
$.paths['/drinks'].get.parameters | Selects the parameters of the get operation on the /drinks path. |
$.paths..parameters[?(@.in=='query')] | Selects all query parameters across all paths. |
$.paths.*[?(@..parameters.*[?(@.in=='query')])] | Selects all operations that have one or more query parameters. |
$.paths.*[?(@..parameters.*[?(@.in=='query')])]['post','get','put','path','delete'].tags | Selects tags of specific operations that have one or more query parameters. |
$.components.schemas.Drink | Selects the Drink schema from the components.schemas object. |
When selecting the object to target for different types of updates, consider the following:
Type of Update | Target Object |
---|---|
Updating a primitive value (string, number, boolean) | The containing object |
Updating an object | The object itself |
Updating an array | The array itself |
Adding a new property to an object | The object itself |
Adding a new item to an array | The array itself |
Removing a property from an object | The object itself |
Removing an item from an array | The array itself |
For example, to update the description
field of the info
object, you would target the info
object itself:
overlay: 1.0.0info:title: Update Speakeasy API descriptionversion: 1.0.0actions:- target: $.infoupdate:description: The Speakeasy Bar API is a secret underground bar that serves drinks to those in the know.
To remove a specific path, such as /oldDrinks
, from the paths
object, you would target that path directly:
overlay: 1.0.0info:title: Remove deprecated drinks pathversion: 1.0.0actions:- target: $.paths['/oldDrinks']remove: true
Applying an Overlay in OpenAPI
When an overlay is applied, the update
object is merged with the targeted objects. Any properties present in both the update
object and the targeted objects will be replaced with the values from the update
object. New properties from the update
object will be added to the targeted objects.
The Overlay document is processed in the following order:
-
Tooling locates the original OpenAPI document to modify. This is based on the
extends
field if provided, otherwise determined by the tooling. -
Each Action Object is applied to the OpenAPI documents in the order they appear in the
actions
array.For each action:
-
The
target
JSONPath expression is evaluated against the OpenAPI document to locate the objects to modify. -
If the
remove
field istrue
, the targeted objects are removed from the OpenAPI document. -
If the
remove
field isfalse
or not provided and anupdate
object is specified, theupdate
object is merged with each of the targeted objects.
-
OpenAPI Overlay Examples
Here are some examples of overlays that could be applied to the Speakeasy Bar OpenAPI document:
Updating Info and Servers
This example demonstrates updating the info
and servers
objects in the original OpenAPI document.
overlay: 1.0.0info:title: Update Speakeasy Bar Info and Serversversion: 1.0.0actions:- target: $.infoupdate:description: The Speakeasy Bar API is a secret underground bar that serves drinks to those in the know.contact:name: Speakeasy Bar Supportemail: support@speakeasy.bar- target: $.serversupdate:- url: https://staging.speakeasy.bar/v1description: Staging server- url: https://api.speakeasy.bar/v1description: Production server
Adding Tags and Updating Drink Responses
This example demonstrates adding tags to the OpenAPI document and updating response objects for operations related to drinks.
overlay: 1.0.0info:title: Add Tags and Update Drink Responsesversion: 1.0.0actions:- target: $.tagsupdate:- name: Drinksdescription: Operations related to managing drinks- name: Ordersdescription: Operations related to order processing- target: $.paths['/drinks'].get.responses[200].content['application/json'].schemaupdate:$ref: "#/components/schemas/DrinkList"- target: $.paths['/drinks/{drinkId}'].get.responses[200].content['application/json'].schemaupdate:$ref: "#/components/schemas/Drink"
Adding Query Parameter Tags
This example demonstrates adding a tag to all operations that have query parameters.
overlay: 1.0.0info:title: Add Query Parameter Tagsversion: 1.0.0actions:- target: $.paths.*[?(@..parameters.*[?(@.in=='query')])]['post','get','put','path','delete'].tagsupdate:- hasQueryParameters
Removing Deprecated Drink Operations
This example demonstrates removing operations related to drinks that have been marked as deprecated.
overlay: 1.0.0info:title: Remove Deprecated Drink Operationsversion: 1.0.0actions:- target: $.paths['/drinks'].*.deprecatedremove: true- target: $.paths['/drinks/{drinkId}'].*.deprecatedremove: true