
OpenAPI Tips
Defining OpenAPI Servers - The Where To Your API's How

Nolan Sullivan
November 24, 2023

Announcing: OpenAPI Reference
Hi! These blog posts have been popular, so we've built an entire OpenAPI Reference Guide to answer any question you have.
It includes detailed information on servers.
Happy Spec Writing!
In this post, we'll take a detailed look at how the OpenAPI Specification (OAS) allows us to define servers in our OpenAPI documents (OADs), then at a few tips to help you provide the best developer experience for your users.
This aspect of API design is often overlooked, but specifying servers in a flexible and robust way can ensure your users know exactly where to send API calls, allows users the flexibility to pick a specific server based on their preference or data-privacy requirements, and allows your developers to switch between development and production environments while testing without editing code.
A Brief History of Base URLs in Swagger (OAS 2.0)
If you have some experience with Swagger 2.0, the predecessor to OpenAPI 3.0, you may recall that specifying servers for your API was somewhat rigid. We're including this to show you how to convert your Swagger 2.0 base URL definition to OpenAPI 3.x later on. If you don't have a Swagger 2.0 document, you can safely skip this section.
In Swagger 2.0, we could define three fields to tell API users where to send requests: host
, basePath
, and schemes
. The host
specified the domain name or IP, the basePath
defined the base path for the API, and schemes
determined the protocols (HTTP or HTTPS) as an array.
Here's an example of the relevant Swagger 2.0 fields:
swagger: "2.0"host: api.example.combasePath: /v1schemes: - https - http# ...
To construct the base URL for requests, the API user should select a scheme, then concatenate the strings to form the URL: schemes[n] + host + basepath
.
The screenshot above illustrates the scheme selector in the Swagger 2.0 editor. The scheme selector is the only option for building a base URL in Swagger 2.0.
Servers in OAS 3.x - Controlled Flexibility
In response to the need for more flexibility, OAS 3.0 introduces the optional servers
schema. The servers
schema allows API users to select a base URL from an array of servers, some of which can include variables - allowing for the construction of more complex base URLs.
Each server in the servers
array consists of an object with at least one field, url
. Each server object can also contain an optional description
field, as well as an optional array of variables
.
Let's look at an OpenAPI 3.1.0 document with three different server objects to illustrate the available options, and how they influence the Swagger UI server selector.
openapi: 3.1.0servers:- url: https://speakeasy.bar- description: The staging server. url: https://staging.speakeasy.bar- description: A per-organization and per-environment API. url: https://{organization}.{environment}.speakeasy.bar variables: environment: default: prod description: The environment name. Defaults to the production environment. enum: - prod - staging - dev organization: default: api description: The organization name. Defaults to a generic organization.info: contact: email: support@speakeasy.bar name: Speakeasy Support url: https://support.speakeasy.bar description: A secret underground bar that serves drinks to those in the know. summary: A bar that serves drinks. title: The Speakeasy Bar version: 1.0.0components: schemas: APIError: properties: code: title: Code type: string details: title: Details type: object message: title: Message type: string title: APIError type: object AuthenticatePostRequest: properties: password: title: Password type: string username: title: Username type: string title: AuthenticatePostRequest type: object AuthenticatePostResponse: properties: token: title: Token type: string title: AuthenticatePostResponse type: object Drink: properties: name: description: The name of the drink. examples: - Old Fashioned - Manhattan - Negroni title: Name type: string price: description: The price of one unit of the drink in US cents. examples: - 1000 - 1200 - 1500 title: Price type: number productCode: description: The product code of the drink, only available when authenticated. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string stock: description: The number of units of the drink in stock, only available when authenticated. title: Stock type: integer type: $ref: '#/components/schemas/DrinkType' required: - name - price title: Drink type: object DrinkType: description: An enumeration. enum: - cocktail - non-alcoholic - beer - wine - spirit - other title: DrinkType Error: properties: code: title: Code type: string message: title: Message type: string title: Error type: object Ingredient: properties: name: description: The name of the ingredient. examples: - Sugar Syrup - Angostura Bitters - Orange Peel title: Name type: string productCode: description: The product code of the ingredient, only available when authenticated. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string stock: description: The number of units of the ingredient in stock, only available when authenticated. examples: - 10 - 5 - 0 title: Stock type: integer type: $ref: '#/components/schemas/IngredientType' required: - name - type title: Ingredient type: object IngredientType: description: An enumeration. enum: - fresh - long-life - packaged title: IngredientType Order: properties: productCode: description: The product code of the drink or ingredient. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string quantity: description: The number of units of the drink or ingredient to order. minimum: 1.0 title: Quantity type: integer status: allOf: - $ref: '#/components/schemas/Status' description: The status of the order. type: $ref: '#/components/schemas/OrderType' required: - type - productCode - quantity - status title: Order type: object OrderType: description: An enumeration. enum: - drink - ingredient title: OrderType Status: description: An enumeration. enum: - pending - processing - complete title: Status Webhook: description: An enumeration. enum: - stockUpdate title: Webhook WebhooksSubscribePostRequest: properties: url: title: Url type: string webhook: $ref: '#/components/schemas/Webhook' title: WebhooksSubscribePostRequest type: objectpaths: /authenticate: post: description: Authenticate with the API by providing a username and password. operationId: authenticate_authenticate_post requestBody: content: application/json: schema: $ref: '#/components/schemas/AuthenticatePostRequest' required: true responses: '200': content: application/json: schema: $ref: '#/components/schemas/AuthenticatePostResponse' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Authenticate tags: - authentication /drink/{name}: get: description: Get a drink. operationId: get_drink_drink__name__get parameters: - in: path name: name required: true schema: title: Name type: string responses: '200': content: application/json: schema: $ref: '#/components/schemas/Drink' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Get Drink tags: - drinks /drinks: get: description: Get a list of drinks. operationId: list_drinks_drinks_get parameters: - in: query name: type required: false schema: $ref: '#/components/schemas/DrinkType' responses: '200': content: application/json: schema: items: $ref: '#/components/schemas/Drink' title: Response List Drinks Drinks Get type: array description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: List Drinks tags: - drinks /ingredients: get: description: Get a list of ingredients. operationId: list_ingredients_ingredients_get requestBody: content: application/json: schema: items: type: string title: Ingredients type: array responses: '200': content: application/json: schema: items: $ref: '#/components/schemas/Ingredient' title: Response List Ingredients Ingredients Get type: array description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: List Ingredients tags: - ingredients /order: post: description: Create an order. operationId: create_order_order_post parameters: - in: query name: callback_url required: false schema: title: Callback Url type: string requestBody: content: application/json: schema: items: $ref: '#/components/schemas/Order' title: Body type: array required: true responses: '200': content: application/json: schema: $ref: '#/components/schemas/Order' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Create Order tags: - orders /webhooks/subscribe: post: description: Subscribe to webhooks. operationId: subscribe_to_webhooks_webhooks_subscribe_post requestBody: content: application/json: schema: items: $ref: '#/components/schemas/WebhooksSubscribePostRequest' title: Body type: array required: true responses: '200': content: application/json: schema: {} description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Subscribe To Webhooks tags: - configuration
The first server object is the simplest. It contains only a url
field, which is a string containing the base URL for the API: https://speakeasy.bar
.
openapi: 3.1.0servers:- url: https://speakeasy.bar- description: The staging server. url: https://staging.speakeasy.bar- description: A per-organization and per-environment API. url: https://{organization}.{environment}.speakeasy.bar variables: environment: default: prod description: The environment name. Defaults to the production environment. enum: - prod - staging - dev organization: default: api description: The organization name. Defaults to a generic organization.info: contact: email: support@speakeasy.bar name: Speakeasy Support url: https://support.speakeasy.bar description: A secret underground bar that serves drinks to those in the know. summary: A bar that serves drinks. title: The Speakeasy Bar version: 1.0.0components: schemas: APIError: properties: code: title: Code type: string details: title: Details type: object message: title: Message type: string title: APIError type: object AuthenticatePostRequest: properties: password: title: Password type: string username: title: Username type: string title: AuthenticatePostRequest type: object AuthenticatePostResponse: properties: token: title: Token type: string title: AuthenticatePostResponse type: object Drink: properties: name: description: The name of the drink. examples: - Old Fashioned - Manhattan - Negroni title: Name type: string price: description: The price of one unit of the drink in US cents. examples: - 1000 - 1200 - 1500 title: Price type: number productCode: description: The product code of the drink, only available when authenticated. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string stock: description: The number of units of the drink in stock, only available when authenticated. title: Stock type: integer type: $ref: '#/components/schemas/DrinkType' required: - name - price title: Drink type: object DrinkType: description: An enumeration. enum: - cocktail - non-alcoholic - beer - wine - spirit - other title: DrinkType Error: properties: code: title: Code type: string message: title: Message type: string title: Error type: object Ingredient: properties: name: description: The name of the ingredient. examples: - Sugar Syrup - Angostura Bitters - Orange Peel title: Name type: string productCode: description: The product code of the ingredient, only available when authenticated. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string stock: description: The number of units of the ingredient in stock, only available when authenticated. examples: - 10 - 5 - 0 title: Stock type: integer type: $ref: '#/components/schemas/IngredientType' required: - name - type title: Ingredient type: object IngredientType: description: An enumeration. enum: - fresh - long-life - packaged title: IngredientType Order: properties: productCode: description: The product code of the drink or ingredient. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string quantity: description: The number of units of the drink or ingredient to order. minimum: 1.0 title: Quantity type: integer status: allOf: - $ref: '#/components/schemas/Status' description: The status of the order. type: $ref: '#/components/schemas/OrderType' required: - type - productCode - quantity - status title: Order type: object OrderType: description: An enumeration. enum: - drink - ingredient title: OrderType Status: description: An enumeration. enum: - pending - processing - complete title: Status Webhook: description: An enumeration. enum: - stockUpdate title: Webhook WebhooksSubscribePostRequest: properties: url: title: Url type: string webhook: $ref: '#/components/schemas/Webhook' title: WebhooksSubscribePostRequest type: objectpaths: /authenticate: post: description: Authenticate with the API by providing a username and password. operationId: authenticate_authenticate_post requestBody: content: application/json: schema: $ref: '#/components/schemas/AuthenticatePostRequest' required: true responses: '200': content: application/json: schema: $ref: '#/components/schemas/AuthenticatePostResponse' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Authenticate tags: - authentication /drink/{name}: get: description: Get a drink. operationId: get_drink_drink__name__get parameters: - in: path name: name required: true schema: title: Name type: string responses: '200': content: application/json: schema: $ref: '#/components/schemas/Drink' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Get Drink tags: - drinks /drinks: get: description: Get a list of drinks. operationId: list_drinks_drinks_get parameters: - in: query name: type required: false schema: $ref: '#/components/schemas/DrinkType' responses: '200': content: application/json: schema: items: $ref: '#/components/schemas/Drink' title: Response List Drinks Drinks Get type: array description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: List Drinks tags: - drinks /ingredients: get: description: Get a list of ingredients. operationId: list_ingredients_ingredients_get requestBody: content: application/json: schema: items: type: string title: Ingredients type: array responses: '200': content: application/json: schema: items: $ref: '#/components/schemas/Ingredient' title: Response List Ingredients Ingredients Get type: array description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: List Ingredients tags: - ingredients /order: post: description: Create an order. operationId: create_order_order_post parameters: - in: query name: callback_url required: false schema: title: Callback Url type: string requestBody: content: application/json: schema: items: $ref: '#/components/schemas/Order' title: Body type: array required: true responses: '200': content: application/json: schema: $ref: '#/components/schemas/Order' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Create Order tags: - orders /webhooks/subscribe: post: description: Subscribe to webhooks. operationId: subscribe_to_webhooks_webhooks_subscribe_post requestBody: content: application/json: schema: items: $ref: '#/components/schemas/WebhooksSubscribePostRequest' title: Body type: array required: true responses: '200': content: application/json: schema: {} description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Subscribe To Webhooks tags: - configuration
The second server object contains a url
field and a description
field. The description
field is a string that can be used to describe the server. This is useful for providing additional information about the server, such as its location or purpose.
openapi: 3.1.0servers:- url: https://speakeasy.bar- description: The staging server. url: https://staging.speakeasy.bar- description: A per-organization and per-environment API. url: https://{organization}.{environment}.speakeasy.bar variables: environment: default: prod description: The environment name. Defaults to the production environment. enum: - prod - staging - dev organization: default: api description: The organization name. Defaults to a generic organization.info: contact: email: support@speakeasy.bar name: Speakeasy Support url: https://support.speakeasy.bar description: A secret underground bar that serves drinks to those in the know. summary: A bar that serves drinks. title: The Speakeasy Bar version: 1.0.0components: schemas: APIError: properties: code: title: Code type: string details: title: Details type: object message: title: Message type: string title: APIError type: object AuthenticatePostRequest: properties: password: title: Password type: string username: title: Username type: string title: AuthenticatePostRequest type: object AuthenticatePostResponse: properties: token: title: Token type: string title: AuthenticatePostResponse type: object Drink: properties: name: description: The name of the drink. examples: - Old Fashioned - Manhattan - Negroni title: Name type: string price: description: The price of one unit of the drink in US cents. examples: - 1000 - 1200 - 1500 title: Price type: number productCode: description: The product code of the drink, only available when authenticated. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string stock: description: The number of units of the drink in stock, only available when authenticated. title: Stock type: integer type: $ref: '#/components/schemas/DrinkType' required: - name - price title: Drink type: object DrinkType: description: An enumeration. enum: - cocktail - non-alcoholic - beer - wine - spirit - other title: DrinkType Error: properties: code: title: Code type: string message: title: Message type: string title: Error type: object Ingredient: properties: name: description: The name of the ingredient. examples: - Sugar Syrup - Angostura Bitters - Orange Peel title: Name type: string productCode: description: The product code of the ingredient, only available when authenticated. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string stock: description: The number of units of the ingredient in stock, only available when authenticated. examples: - 10 - 5 - 0 title: Stock type: integer type: $ref: '#/components/schemas/IngredientType' required: - name - type title: Ingredient type: object IngredientType: description: An enumeration. enum: - fresh - long-life - packaged title: IngredientType Order: properties: productCode: description: The product code of the drink or ingredient. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string quantity: description: The number of units of the drink or ingredient to order. minimum: 1.0 title: Quantity type: integer status: allOf: - $ref: '#/components/schemas/Status' description: The status of the order. type: $ref: '#/components/schemas/OrderType' required: - type - productCode - quantity - status title: Order type: object OrderType: description: An enumeration. enum: - drink - ingredient title: OrderType Status: description: An enumeration. enum: - pending - processing - complete title: Status Webhook: description: An enumeration. enum: - stockUpdate title: Webhook WebhooksSubscribePostRequest: properties: url: title: Url type: string webhook: $ref: '#/components/schemas/Webhook' title: WebhooksSubscribePostRequest type: objectpaths: /authenticate: post: description: Authenticate with the API by providing a username and password. operationId: authenticate_authenticate_post requestBody: content: application/json: schema: $ref: '#/components/schemas/AuthenticatePostRequest' required: true responses: '200': content: application/json: schema: $ref: '#/components/schemas/AuthenticatePostResponse' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Authenticate tags: - authentication /drink/{name}: get: description: Get a drink. operationId: get_drink_drink__name__get parameters: - in: path name: name required: true schema: title: Name type: string responses: '200': content: application/json: schema: $ref: '#/components/schemas/Drink' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Get Drink tags: - drinks /drinks: get: description: Get a list of drinks. operationId: list_drinks_drinks_get parameters: - in: query name: type required: false schema: $ref: '#/components/schemas/DrinkType' responses: '200': content: application/json: schema: items: $ref: '#/components/schemas/Drink' title: Response List Drinks Drinks Get type: array description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: List Drinks tags: - drinks /ingredients: get: description: Get a list of ingredients. operationId: list_ingredients_ingredients_get requestBody: content: application/json: schema: items: type: string title: Ingredients type: array responses: '200': content: application/json: schema: items: $ref: '#/components/schemas/Ingredient' title: Response List Ingredients Ingredients Get type: array description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: List Ingredients tags: - ingredients /order: post: description: Create an order. operationId: create_order_order_post parameters: - in: query name: callback_url required: false schema: title: Callback Url type: string requestBody: content: application/json: schema: items: $ref: '#/components/schemas/Order' title: Body type: array required: true responses: '200': content: application/json: schema: $ref: '#/components/schemas/Order' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Create Order tags: - orders /webhooks/subscribe: post: description: Subscribe to webhooks. operationId: subscribe_to_webhooks_webhooks_subscribe_post requestBody: content: application/json: schema: items: $ref: '#/components/schemas/WebhooksSubscribePostRequest' title: Body type: array required: true responses: '200': content: application/json: schema: {} description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Subscribe To Webhooks tags: - configuration
In our example, the description
field is used to describe the server as the staging server.
openapi: 3.1.0servers:- url: https://speakeasy.bar- description: The staging server. url: https://staging.speakeasy.bar- description: A per-organization and per-environment API. url: https://{organization}.{environment}.speakeasy.bar variables: environment: default: prod description: The environment name. Defaults to the production environment. enum: - prod - staging - dev organization: default: api description: The organization name. Defaults to a generic organization.info: contact: email: support@speakeasy.bar name: Speakeasy Support url: https://support.speakeasy.bar description: A secret underground bar that serves drinks to those in the know. summary: A bar that serves drinks. title: The Speakeasy Bar version: 1.0.0components: schemas: APIError: properties: code: title: Code type: string details: title: Details type: object message: title: Message type: string title: APIError type: object AuthenticatePostRequest: properties: password: title: Password type: string username: title: Username type: string title: AuthenticatePostRequest type: object AuthenticatePostResponse: properties: token: title: Token type: string title: AuthenticatePostResponse type: object Drink: properties: name: description: The name of the drink. examples: - Old Fashioned - Manhattan - Negroni title: Name type: string price: description: The price of one unit of the drink in US cents. examples: - 1000 - 1200 - 1500 title: Price type: number productCode: description: The product code of the drink, only available when authenticated. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string stock: description: The number of units of the drink in stock, only available when authenticated. title: Stock type: integer type: $ref: '#/components/schemas/DrinkType' required: - name - price title: Drink type: object DrinkType: description: An enumeration. enum: - cocktail - non-alcoholic - beer - wine - spirit - other title: DrinkType Error: properties: code: title: Code type: string message: title: Message type: string title: Error type: object Ingredient: properties: name: description: The name of the ingredient. examples: - Sugar Syrup - Angostura Bitters - Orange Peel title: Name type: string productCode: description: The product code of the ingredient, only available when authenticated. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string stock: description: The number of units of the ingredient in stock, only available when authenticated. examples: - 10 - 5 - 0 title: Stock type: integer type: $ref: '#/components/schemas/IngredientType' required: - name - type title: Ingredient type: object IngredientType: description: An enumeration. enum: - fresh - long-life - packaged title: IngredientType Order: properties: productCode: description: The product code of the drink or ingredient. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string quantity: description: The number of units of the drink or ingredient to order. minimum: 1.0 title: Quantity type: integer status: allOf: - $ref: '#/components/schemas/Status' description: The status of the order. type: $ref: '#/components/schemas/OrderType' required: - type - productCode - quantity - status title: Order type: object OrderType: description: An enumeration. enum: - drink - ingredient title: OrderType Status: description: An enumeration. enum: - pending - processing - complete title: Status Webhook: description: An enumeration. enum: - stockUpdate title: Webhook WebhooksSubscribePostRequest: properties: url: title: Url type: string webhook: $ref: '#/components/schemas/Webhook' title: WebhooksSubscribePostRequest type: objectpaths: /authenticate: post: description: Authenticate with the API by providing a username and password. operationId: authenticate_authenticate_post requestBody: content: application/json: schema: $ref: '#/components/schemas/AuthenticatePostRequest' required: true responses: '200': content: application/json: schema: $ref: '#/components/schemas/AuthenticatePostResponse' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Authenticate tags: - authentication /drink/{name}: get: description: Get a drink. operationId: get_drink_drink__name__get parameters: - in: path name: name required: true schema: title: Name type: string responses: '200': content: application/json: schema: $ref: '#/components/schemas/Drink' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Get Drink tags: - drinks /drinks: get: description: Get a list of drinks. operationId: list_drinks_drinks_get parameters: - in: query name: type required: false schema: $ref: '#/components/schemas/DrinkType' responses: '200': content: application/json: schema: items: $ref: '#/components/schemas/Drink' title: Response List Drinks Drinks Get type: array description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: List Drinks tags: - drinks /ingredients: get: description: Get a list of ingredients. operationId: list_ingredients_ingredients_get requestBody: content: application/json: schema: items: type: string title: Ingredients type: array responses: '200': content: application/json: schema: items: $ref: '#/components/schemas/Ingredient' title: Response List Ingredients Ingredients Get type: array description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: List Ingredients tags: - ingredients /order: post: description: Create an order. operationId: create_order_order_post parameters: - in: query name: callback_url required: false schema: title: Callback Url type: string requestBody: content: application/json: schema: items: $ref: '#/components/schemas/Order' title: Body type: array required: true responses: '200': content: application/json: schema: $ref: '#/components/schemas/Order' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Create Order tags: - orders /webhooks/subscribe: post: description: Subscribe to webhooks. operationId: subscribe_to_webhooks_webhooks_subscribe_post requestBody: content: application/json: schema: items: $ref: '#/components/schemas/WebhooksSubscribePostRequest' title: Body type: array required: true responses: '200': content: application/json: schema: {} description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Subscribe To Webhooks tags: - configuration
The third server object contains a url
field, a description
field, and a variables
field. The variables
field is an array of objects that define variables that can be used to construct the base URL.
openapi: 3.1.0servers:- url: https://speakeasy.bar- description: The staging server. url: https://staging.speakeasy.bar- description: A per-organization and per-environment API. url: https://{organization}.{environment}.speakeasy.bar variables: environment: default: prod description: The environment name. Defaults to the production environment. enum: - prod - staging - dev organization: default: api description: The organization name. Defaults to a generic organization.info: contact: email: support@speakeasy.bar name: Speakeasy Support url: https://support.speakeasy.bar description: A secret underground bar that serves drinks to those in the know. summary: A bar that serves drinks. title: The Speakeasy Bar version: 1.0.0components: schemas: APIError: properties: code: title: Code type: string details: title: Details type: object message: title: Message type: string title: APIError type: object AuthenticatePostRequest: properties: password: title: Password type: string username: title: Username type: string title: AuthenticatePostRequest type: object AuthenticatePostResponse: properties: token: title: Token type: string title: AuthenticatePostResponse type: object Drink: properties: name: description: The name of the drink. examples: - Old Fashioned - Manhattan - Negroni title: Name type: string price: description: The price of one unit of the drink in US cents. examples: - 1000 - 1200 - 1500 title: Price type: number productCode: description: The product code of the drink, only available when authenticated. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string stock: description: The number of units of the drink in stock, only available when authenticated. title: Stock type: integer type: $ref: '#/components/schemas/DrinkType' required: - name - price title: Drink type: object DrinkType: description: An enumeration. enum: - cocktail - non-alcoholic - beer - wine - spirit - other title: DrinkType Error: properties: code: title: Code type: string message: title: Message type: string title: Error type: object Ingredient: properties: name: description: The name of the ingredient. examples: - Sugar Syrup - Angostura Bitters - Orange Peel title: Name type: string productCode: description: The product code of the ingredient, only available when authenticated. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string stock: description: The number of units of the ingredient in stock, only available when authenticated. examples: - 10 - 5 - 0 title: Stock type: integer type: $ref: '#/components/schemas/IngredientType' required: - name - type title: Ingredient type: object IngredientType: description: An enumeration. enum: - fresh - long-life - packaged title: IngredientType Order: properties: productCode: description: The product code of the drink or ingredient. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string quantity: description: The number of units of the drink or ingredient to order. minimum: 1.0 title: Quantity type: integer status: allOf: - $ref: '#/components/schemas/Status' description: The status of the order. type: $ref: '#/components/schemas/OrderType' required: - type - productCode - quantity - status title: Order type: object OrderType: description: An enumeration. enum: - drink - ingredient title: OrderType Status: description: An enumeration. enum: - pending - processing - complete title: Status Webhook: description: An enumeration. enum: - stockUpdate title: Webhook WebhooksSubscribePostRequest: properties: url: title: Url type: string webhook: $ref: '#/components/schemas/Webhook' title: WebhooksSubscribePostRequest type: objectpaths: /authenticate: post: description: Authenticate with the API by providing a username and password. operationId: authenticate_authenticate_post requestBody: content: application/json: schema: $ref: '#/components/schemas/AuthenticatePostRequest' required: true responses: '200': content: application/json: schema: $ref: '#/components/schemas/AuthenticatePostResponse' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Authenticate tags: - authentication /drink/{name}: get: description: Get a drink. operationId: get_drink_drink__name__get parameters: - in: path name: name required: true schema: title: Name type: string responses: '200': content: application/json: schema: $ref: '#/components/schemas/Drink' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Get Drink tags: - drinks /drinks: get: description: Get a list of drinks. operationId: list_drinks_drinks_get parameters: - in: query name: type required: false schema: $ref: '#/components/schemas/DrinkType' responses: '200': content: application/json: schema: items: $ref: '#/components/schemas/Drink' title: Response List Drinks Drinks Get type: array description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: List Drinks tags: - drinks /ingredients: get: description: Get a list of ingredients. operationId: list_ingredients_ingredients_get requestBody: content: application/json: schema: items: type: string title: Ingredients type: array responses: '200': content: application/json: schema: items: $ref: '#/components/schemas/Ingredient' title: Response List Ingredients Ingredients Get type: array description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: List Ingredients tags: - ingredients /order: post: description: Create an order. operationId: create_order_order_post parameters: - in: query name: callback_url required: false schema: title: Callback Url type: string requestBody: content: application/json: schema: items: $ref: '#/components/schemas/Order' title: Body type: array required: true responses: '200': content: application/json: schema: $ref: '#/components/schemas/Order' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Create Order tags: - orders /webhooks/subscribe: post: description: Subscribe to webhooks. operationId: subscribe_to_webhooks_webhooks_subscribe_post requestBody: content: application/json: schema: items: $ref: '#/components/schemas/WebhooksSubscribePostRequest' title: Body type: array required: true responses: '200': content: application/json: schema: {} description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Subscribe To Webhooks tags: - configuration
In this example, the URL is a template string that contains two variables: organization
and environment
.
openapi: 3.1.0servers:- url: https://speakeasy.bar- description: The staging server. url: https://staging.speakeasy.bar- description: A per-organization and per-environment API. url: https://{organization}.{environment}.speakeasy.bar variables: environment: default: prod description: The environment name. Defaults to the production environment. enum: - prod - staging - dev organization: default: api description: The organization name. Defaults to a generic organization.info: contact: email: support@speakeasy.bar name: Speakeasy Support url: https://support.speakeasy.bar description: A secret underground bar that serves drinks to those in the know. summary: A bar that serves drinks. title: The Speakeasy Bar version: 1.0.0components: schemas: APIError: properties: code: title: Code type: string details: title: Details type: object message: title: Message type: string title: APIError type: object AuthenticatePostRequest: properties: password: title: Password type: string username: title: Username type: string title: AuthenticatePostRequest type: object AuthenticatePostResponse: properties: token: title: Token type: string title: AuthenticatePostResponse type: object Drink: properties: name: description: The name of the drink. examples: - Old Fashioned - Manhattan - Negroni title: Name type: string price: description: The price of one unit of the drink in US cents. examples: - 1000 - 1200 - 1500 title: Price type: number productCode: description: The product code of the drink, only available when authenticated. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string stock: description: The number of units of the drink in stock, only available when authenticated. title: Stock type: integer type: $ref: '#/components/schemas/DrinkType' required: - name - price title: Drink type: object DrinkType: description: An enumeration. enum: - cocktail - non-alcoholic - beer - wine - spirit - other title: DrinkType Error: properties: code: title: Code type: string message: title: Message type: string title: Error type: object Ingredient: properties: name: description: The name of the ingredient. examples: - Sugar Syrup - Angostura Bitters - Orange Peel title: Name type: string productCode: description: The product code of the ingredient, only available when authenticated. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string stock: description: The number of units of the ingredient in stock, only available when authenticated. examples: - 10 - 5 - 0 title: Stock type: integer type: $ref: '#/components/schemas/IngredientType' required: - name - type title: Ingredient type: object IngredientType: description: An enumeration. enum: - fresh - long-life - packaged title: IngredientType Order: properties: productCode: description: The product code of the drink or ingredient. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string quantity: description: The number of units of the drink or ingredient to order. minimum: 1.0 title: Quantity type: integer status: allOf: - $ref: '#/components/schemas/Status' description: The status of the order. type: $ref: '#/components/schemas/OrderType' required: - type - productCode - quantity - status title: Order type: object OrderType: description: An enumeration. enum: - drink - ingredient title: OrderType Status: description: An enumeration. enum: - pending - processing - complete title: Status Webhook: description: An enumeration. enum: - stockUpdate title: Webhook WebhooksSubscribePostRequest: properties: url: title: Url type: string webhook: $ref: '#/components/schemas/Webhook' title: WebhooksSubscribePostRequest type: objectpaths: /authenticate: post: description: Authenticate with the API by providing a username and password. operationId: authenticate_authenticate_post requestBody: content: application/json: schema: $ref: '#/components/schemas/AuthenticatePostRequest' required: true responses: '200': content: application/json: schema: $ref: '#/components/schemas/AuthenticatePostResponse' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Authenticate tags: - authentication /drink/{name}: get: description: Get a drink. operationId: get_drink_drink__name__get parameters: - in: path name: name required: true schema: title: Name type: string responses: '200': content: application/json: schema: $ref: '#/components/schemas/Drink' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Get Drink tags: - drinks /drinks: get: description: Get a list of drinks. operationId: list_drinks_drinks_get parameters: - in: query name: type required: false schema: $ref: '#/components/schemas/DrinkType' responses: '200': content: application/json: schema: items: $ref: '#/components/schemas/Drink' title: Response List Drinks Drinks Get type: array description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: List Drinks tags: - drinks /ingredients: get: description: Get a list of ingredients. operationId: list_ingredients_ingredients_get requestBody: content: application/json: schema: items: type: string title: Ingredients type: array responses: '200': content: application/json: schema: items: $ref: '#/components/schemas/Ingredient' title: Response List Ingredients Ingredients Get type: array description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: List Ingredients tags: - ingredients /order: post: description: Create an order. operationId: create_order_order_post parameters: - in: query name: callback_url required: false schema: title: Callback Url type: string requestBody: content: application/json: schema: items: $ref: '#/components/schemas/Order' title: Body type: array required: true responses: '200': content: application/json: schema: $ref: '#/components/schemas/Order' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Create Order tags: - orders /webhooks/subscribe: post: description: Subscribe to webhooks. operationId: subscribe_to_webhooks_webhooks_subscribe_post requestBody: content: application/json: schema: items: $ref: '#/components/schemas/WebhooksSubscribePostRequest' title: Body type: array required: true responses: '200': content: application/json: schema: {} description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Subscribe To Webhooks tags: - configuration
Each variable's name is defined by the object's key.
openapi: 3.1.0servers:- url: https://speakeasy.bar- description: The staging server. url: https://staging.speakeasy.bar- description: A per-organization and per-environment API. url: https://{organization}.{environment}.speakeasy.bar variables: environment: default: prod description: The environment name. Defaults to the production environment. enum: - prod - staging - dev organization: default: api description: The organization name. Defaults to a generic organization.info: contact: email: support@speakeasy.bar name: Speakeasy Support url: https://support.speakeasy.bar description: A secret underground bar that serves drinks to those in the know. summary: A bar that serves drinks. title: The Speakeasy Bar version: 1.0.0components: schemas: APIError: properties: code: title: Code type: string details: title: Details type: object message: title: Message type: string title: APIError type: object AuthenticatePostRequest: properties: password: title: Password type: string username: title: Username type: string title: AuthenticatePostRequest type: object AuthenticatePostResponse: properties: token: title: Token type: string title: AuthenticatePostResponse type: object Drink: properties: name: description: The name of the drink. examples: - Old Fashioned - Manhattan - Negroni title: Name type: string price: description: The price of one unit of the drink in US cents. examples: - 1000 - 1200 - 1500 title: Price type: number productCode: description: The product code of the drink, only available when authenticated. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string stock: description: The number of units of the drink in stock, only available when authenticated. title: Stock type: integer type: $ref: '#/components/schemas/DrinkType' required: - name - price title: Drink type: object DrinkType: description: An enumeration. enum: - cocktail - non-alcoholic - beer - wine - spirit - other title: DrinkType Error: properties: code: title: Code type: string message: title: Message type: string title: Error type: object Ingredient: properties: name: description: The name of the ingredient. examples: - Sugar Syrup - Angostura Bitters - Orange Peel title: Name type: string productCode: description: The product code of the ingredient, only available when authenticated. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string stock: description: The number of units of the ingredient in stock, only available when authenticated. examples: - 10 - 5 - 0 title: Stock type: integer type: $ref: '#/components/schemas/IngredientType' required: - name - type title: Ingredient type: object IngredientType: description: An enumeration. enum: - fresh - long-life - packaged title: IngredientType Order: properties: productCode: description: The product code of the drink or ingredient. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string quantity: description: The number of units of the drink or ingredient to order. minimum: 1.0 title: Quantity type: integer status: allOf: - $ref: '#/components/schemas/Status' description: The status of the order. type: $ref: '#/components/schemas/OrderType' required: - type - productCode - quantity - status title: Order type: object OrderType: description: An enumeration. enum: - drink - ingredient title: OrderType Status: description: An enumeration. enum: - pending - processing - complete title: Status Webhook: description: An enumeration. enum: - stockUpdate title: Webhook WebhooksSubscribePostRequest: properties: url: title: Url type: string webhook: $ref: '#/components/schemas/Webhook' title: WebhooksSubscribePostRequest type: objectpaths: /authenticate: post: description: Authenticate with the API by providing a username and password. operationId: authenticate_authenticate_post requestBody: content: application/json: schema: $ref: '#/components/schemas/AuthenticatePostRequest' required: true responses: '200': content: application/json: schema: $ref: '#/components/schemas/AuthenticatePostResponse' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Authenticate tags: - authentication /drink/{name}: get: description: Get a drink. operationId: get_drink_drink__name__get parameters: - in: path name: name required: true schema: title: Name type: string responses: '200': content: application/json: schema: $ref: '#/components/schemas/Drink' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Get Drink tags: - drinks /drinks: get: description: Get a list of drinks. operationId: list_drinks_drinks_get parameters: - in: query name: type required: false schema: $ref: '#/components/schemas/DrinkType' responses: '200': content: application/json: schema: items: $ref: '#/components/schemas/Drink' title: Response List Drinks Drinks Get type: array description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: List Drinks tags: - drinks /ingredients: get: description: Get a list of ingredients. operationId: list_ingredients_ingredients_get requestBody: content: application/json: schema: items: type: string title: Ingredients type: array responses: '200': content: application/json: schema: items: $ref: '#/components/schemas/Ingredient' title: Response List Ingredients Ingredients Get type: array description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: List Ingredients tags: - ingredients /order: post: description: Create an order. operationId: create_order_order_post parameters: - in: query name: callback_url required: false schema: title: Callback Url type: string requestBody: content: application/json: schema: items: $ref: '#/components/schemas/Order' title: Body type: array required: true responses: '200': content: application/json: schema: $ref: '#/components/schemas/Order' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Create Order tags: - orders /webhooks/subscribe: post: description: Subscribe to webhooks. operationId: subscribe_to_webhooks_webhooks_subscribe_post requestBody: content: application/json: schema: items: $ref: '#/components/schemas/WebhooksSubscribePostRequest' title: Body type: array required: true responses: '200': content: application/json: schema: {} description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Subscribe To Webhooks tags: - configuration
The default
field is a string that defines the default value for the variable.
openapi: 3.1.0servers:- url: https://speakeasy.bar- description: The staging server. url: https://staging.speakeasy.bar- description: A per-organization and per-environment API. url: https://{organization}.{environment}.speakeasy.bar variables: environment: default: prod description: The environment name. Defaults to the production environment. enum: - prod - staging - dev organization: default: api description: The organization name. Defaults to a generic organization.info: contact: email: support@speakeasy.bar name: Speakeasy Support url: https://support.speakeasy.bar description: A secret underground bar that serves drinks to those in the know. summary: A bar that serves drinks. title: The Speakeasy Bar version: 1.0.0components: schemas: APIError: properties: code: title: Code type: string details: title: Details type: object message: title: Message type: string title: APIError type: object AuthenticatePostRequest: properties: password: title: Password type: string username: title: Username type: string title: AuthenticatePostRequest type: object AuthenticatePostResponse: properties: token: title: Token type: string title: AuthenticatePostResponse type: object Drink: properties: name: description: The name of the drink. examples: - Old Fashioned - Manhattan - Negroni title: Name type: string price: description: The price of one unit of the drink in US cents. examples: - 1000 - 1200 - 1500 title: Price type: number productCode: description: The product code of the drink, only available when authenticated. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string stock: description: The number of units of the drink in stock, only available when authenticated. title: Stock type: integer type: $ref: '#/components/schemas/DrinkType' required: - name - price title: Drink type: object DrinkType: description: An enumeration. enum: - cocktail - non-alcoholic - beer - wine - spirit - other title: DrinkType Error: properties: code: title: Code type: string message: title: Message type: string title: Error type: object Ingredient: properties: name: description: The name of the ingredient. examples: - Sugar Syrup - Angostura Bitters - Orange Peel title: Name type: string productCode: description: The product code of the ingredient, only available when authenticated. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string stock: description: The number of units of the ingredient in stock, only available when authenticated. examples: - 10 - 5 - 0 title: Stock type: integer type: $ref: '#/components/schemas/IngredientType' required: - name - type title: Ingredient type: object IngredientType: description: An enumeration. enum: - fresh - long-life - packaged title: IngredientType Order: properties: productCode: description: The product code of the drink or ingredient. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string quantity: description: The number of units of the drink or ingredient to order. minimum: 1.0 title: Quantity type: integer status: allOf: - $ref: '#/components/schemas/Status' description: The status of the order. type: $ref: '#/components/schemas/OrderType' required: - type - productCode - quantity - status title: Order type: object OrderType: description: An enumeration. enum: - drink - ingredient title: OrderType Status: description: An enumeration. enum: - pending - processing - complete title: Status Webhook: description: An enumeration. enum: - stockUpdate title: Webhook WebhooksSubscribePostRequest: properties: url: title: Url type: string webhook: $ref: '#/components/schemas/Webhook' title: WebhooksSubscribePostRequest type: objectpaths: /authenticate: post: description: Authenticate with the API by providing a username and password. operationId: authenticate_authenticate_post requestBody: content: application/json: schema: $ref: '#/components/schemas/AuthenticatePostRequest' required: true responses: '200': content: application/json: schema: $ref: '#/components/schemas/AuthenticatePostResponse' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Authenticate tags: - authentication /drink/{name}: get: description: Get a drink. operationId: get_drink_drink__name__get parameters: - in: path name: name required: true schema: title: Name type: string responses: '200': content: application/json: schema: $ref: '#/components/schemas/Drink' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Get Drink tags: - drinks /drinks: get: description: Get a list of drinks. operationId: list_drinks_drinks_get parameters: - in: query name: type required: false schema: $ref: '#/components/schemas/DrinkType' responses: '200': content: application/json: schema: items: $ref: '#/components/schemas/Drink' title: Response List Drinks Drinks Get type: array description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: List Drinks tags: - drinks /ingredients: get: description: Get a list of ingredients. operationId: list_ingredients_ingredients_get requestBody: content: application/json: schema: items: type: string title: Ingredients type: array responses: '200': content: application/json: schema: items: $ref: '#/components/schemas/Ingredient' title: Response List Ingredients Ingredients Get type: array description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: List Ingredients tags: - ingredients /order: post: description: Create an order. operationId: create_order_order_post parameters: - in: query name: callback_url required: false schema: title: Callback Url type: string requestBody: content: application/json: schema: items: $ref: '#/components/schemas/Order' title: Body type: array required: true responses: '200': content: application/json: schema: $ref: '#/components/schemas/Order' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Create Order tags: - orders /webhooks/subscribe: post: description: Subscribe to webhooks. operationId: subscribe_to_webhooks_webhooks_subscribe_post requestBody: content: application/json: schema: items: $ref: '#/components/schemas/WebhooksSubscribePostRequest' title: Body type: array required: true responses: '200': content: application/json: schema: {} description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Subscribe To Webhooks tags: - configuration
The enum
field is an array of strings that define the possible values for the variable.
openapi: 3.1.0servers:- url: https://speakeasy.bar- description: The staging server. url: https://staging.speakeasy.bar- description: A per-organization and per-environment API. url: https://{organization}.{environment}.speakeasy.bar variables: environment: default: prod description: The environment name. Defaults to the production environment. enum: - prod - staging - dev organization: default: api description: The organization name. Defaults to a generic organization.info: contact: email: support@speakeasy.bar name: Speakeasy Support url: https://support.speakeasy.bar description: A secret underground bar that serves drinks to those in the know. summary: A bar that serves drinks. title: The Speakeasy Bar version: 1.0.0components: schemas: APIError: properties: code: title: Code type: string details: title: Details type: object message: title: Message type: string title: APIError type: object AuthenticatePostRequest: properties: password: title: Password type: string username: title: Username type: string title: AuthenticatePostRequest type: object AuthenticatePostResponse: properties: token: title: Token type: string title: AuthenticatePostResponse type: object Drink: properties: name: description: The name of the drink. examples: - Old Fashioned - Manhattan - Negroni title: Name type: string price: description: The price of one unit of the drink in US cents. examples: - 1000 - 1200 - 1500 title: Price type: number productCode: description: The product code of the drink, only available when authenticated. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string stock: description: The number of units of the drink in stock, only available when authenticated. title: Stock type: integer type: $ref: '#/components/schemas/DrinkType' required: - name - price title: Drink type: object DrinkType: description: An enumeration. enum: - cocktail - non-alcoholic - beer - wine - spirit - other title: DrinkType Error: properties: code: title: Code type: string message: title: Message type: string title: Error type: object Ingredient: properties: name: description: The name of the ingredient. examples: - Sugar Syrup - Angostura Bitters - Orange Peel title: Name type: string productCode: description: The product code of the ingredient, only available when authenticated. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string stock: description: The number of units of the ingredient in stock, only available when authenticated. examples: - 10 - 5 - 0 title: Stock type: integer type: $ref: '#/components/schemas/IngredientType' required: - name - type title: Ingredient type: object IngredientType: description: An enumeration. enum: - fresh - long-life - packaged title: IngredientType Order: properties: productCode: description: The product code of the drink or ingredient. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string quantity: description: The number of units of the drink or ingredient to order. minimum: 1.0 title: Quantity type: integer status: allOf: - $ref: '#/components/schemas/Status' description: The status of the order. type: $ref: '#/components/schemas/OrderType' required: - type - productCode - quantity - status title: Order type: object OrderType: description: An enumeration. enum: - drink - ingredient title: OrderType Status: description: An enumeration. enum: - pending - processing - complete title: Status Webhook: description: An enumeration. enum: - stockUpdate title: Webhook WebhooksSubscribePostRequest: properties: url: title: Url type: string webhook: $ref: '#/components/schemas/Webhook' title: WebhooksSubscribePostRequest type: objectpaths: /authenticate: post: description: Authenticate with the API by providing a username and password. operationId: authenticate_authenticate_post requestBody: content: application/json: schema: $ref: '#/components/schemas/AuthenticatePostRequest' required: true responses: '200': content: application/json: schema: $ref: '#/components/schemas/AuthenticatePostResponse' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Authenticate tags: - authentication /drink/{name}: get: description: Get a drink. operationId: get_drink_drink__name__get parameters: - in: path name: name required: true schema: title: Name type: string responses: '200': content: application/json: schema: $ref: '#/components/schemas/Drink' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Get Drink tags: - drinks /drinks: get: description: Get a list of drinks. operationId: list_drinks_drinks_get parameters: - in: query name: type required: false schema: $ref: '#/components/schemas/DrinkType' responses: '200': content: application/json: schema: items: $ref: '#/components/schemas/Drink' title: Response List Drinks Drinks Get type: array description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: List Drinks tags: - drinks /ingredients: get: description: Get a list of ingredients. operationId: list_ingredients_ingredients_get requestBody: content: application/json: schema: items: type: string title: Ingredients type: array responses: '200': content: application/json: schema: items: $ref: '#/components/schemas/Ingredient' title: Response List Ingredients Ingredients Get type: array description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: List Ingredients tags: - ingredients /order: post: description: Create an order. operationId: create_order_order_post parameters: - in: query name: callback_url required: false schema: title: Callback Url type: string requestBody: content: application/json: schema: items: $ref: '#/components/schemas/Order' title: Body type: array required: true responses: '200': content: application/json: schema: $ref: '#/components/schemas/Order' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Create Order tags: - orders /webhooks/subscribe: post: description: Subscribe to webhooks. operationId: subscribe_to_webhooks_webhooks_subscribe_post requestBody: content: application/json: schema: items: $ref: '#/components/schemas/WebhooksSubscribePostRequest' title: Body type: array required: true responses: '200': content: application/json: schema: {} description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Subscribe To Webhooks tags: - configuration
The description
field is a string that can be used to describe the variable. This is useful for providing additional information about the variable, such as its purpose.
This field is not used by the OpenAPI documentation generator, but it can be used by other tools to provide additional information to API users.
openapi: 3.1.0servers:- url: https://speakeasy.bar- description: The staging server. url: https://staging.speakeasy.bar- description: A per-organization and per-environment API. url: https://{organization}.{environment}.speakeasy.bar variables: environment: default: prod description: The environment name. Defaults to the production environment. enum: - prod - staging - dev organization: default: api description: The organization name. Defaults to a generic organization.info: contact: email: support@speakeasy.bar name: Speakeasy Support url: https://support.speakeasy.bar description: A secret underground bar that serves drinks to those in the know. summary: A bar that serves drinks. title: The Speakeasy Bar version: 1.0.0components: schemas: APIError: properties: code: title: Code type: string details: title: Details type: object message: title: Message type: string title: APIError type: object AuthenticatePostRequest: properties: password: title: Password type: string username: title: Username type: string title: AuthenticatePostRequest type: object AuthenticatePostResponse: properties: token: title: Token type: string title: AuthenticatePostResponse type: object Drink: properties: name: description: The name of the drink. examples: - Old Fashioned - Manhattan - Negroni title: Name type: string price: description: The price of one unit of the drink in US cents. examples: - 1000 - 1200 - 1500 title: Price type: number productCode: description: The product code of the drink, only available when authenticated. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string stock: description: The number of units of the drink in stock, only available when authenticated. title: Stock type: integer type: $ref: '#/components/schemas/DrinkType' required: - name - price title: Drink type: object DrinkType: description: An enumeration. enum: - cocktail - non-alcoholic - beer - wine - spirit - other title: DrinkType Error: properties: code: title: Code type: string message: title: Message type: string title: Error type: object Ingredient: properties: name: description: The name of the ingredient. examples: - Sugar Syrup - Angostura Bitters - Orange Peel title: Name type: string productCode: description: The product code of the ingredient, only available when authenticated. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string stock: description: The number of units of the ingredient in stock, only available when authenticated. examples: - 10 - 5 - 0 title: Stock type: integer type: $ref: '#/components/schemas/IngredientType' required: - name - type title: Ingredient type: object IngredientType: description: An enumeration. enum: - fresh - long-life - packaged title: IngredientType Order: properties: productCode: description: The product code of the drink or ingredient. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string quantity: description: The number of units of the drink or ingredient to order. minimum: 1.0 title: Quantity type: integer status: allOf: - $ref: '#/components/schemas/Status' description: The status of the order. type: $ref: '#/components/schemas/OrderType' required: - type - productCode - quantity - status title: Order type: object OrderType: description: An enumeration. enum: - drink - ingredient title: OrderType Status: description: An enumeration. enum: - pending - processing - complete title: Status Webhook: description: An enumeration. enum: - stockUpdate title: Webhook WebhooksSubscribePostRequest: properties: url: title: Url type: string webhook: $ref: '#/components/schemas/Webhook' title: WebhooksSubscribePostRequest type: objectpaths: /authenticate: post: description: Authenticate with the API by providing a username and password. operationId: authenticate_authenticate_post requestBody: content: application/json: schema: $ref: '#/components/schemas/AuthenticatePostRequest' required: true responses: '200': content: application/json: schema: $ref: '#/components/schemas/AuthenticatePostResponse' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Authenticate tags: - authentication /drink/{name}: get: description: Get a drink. operationId: get_drink_drink__name__get parameters: - in: path name: name required: true schema: title: Name type: string responses: '200': content: application/json: schema: $ref: '#/components/schemas/Drink' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Get Drink tags: - drinks /drinks: get: description: Get a list of drinks. operationId: list_drinks_drinks_get parameters: - in: query name: type required: false schema: $ref: '#/components/schemas/DrinkType' responses: '200': content: application/json: schema: items: $ref: '#/components/schemas/Drink' title: Response List Drinks Drinks Get type: array description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: List Drinks tags: - drinks /ingredients: get: description: Get a list of ingredients. operationId: list_ingredients_ingredients_get requestBody: content: application/json: schema: items: type: string title: Ingredients type: array responses: '200': content: application/json: schema: items: $ref: '#/components/schemas/Ingredient' title: Response List Ingredients Ingredients Get type: array description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: List Ingredients tags: - ingredients /order: post: description: Create an order. operationId: create_order_order_post parameters: - in: query name: callback_url required: false schema: title: Callback Url type: string requestBody: content: application/json: schema: items: $ref: '#/components/schemas/Order' title: Body type: array required: true responses: '200': content: application/json: schema: $ref: '#/components/schemas/Order' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Create Order tags: - orders /webhooks/subscribe: post: description: Subscribe to webhooks. operationId: subscribe_to_webhooks_webhooks_subscribe_post requestBody: content: application/json: schema: items: $ref: '#/components/schemas/WebhooksSubscribePostRequest' title: Body type: array required: true responses: '200': content: application/json: schema: {} description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Subscribe To Webhooks tags: - configuration
Let's look at an OpenAPI 3.1.0 document with three different server objects to illustrate the available options, and how they influence the Swagger UI server selector.
The first server object is the simplest. It contains only a url
field, which is a string containing the base URL for the API: https://speakeasy.bar
.
The second server object contains a url
field and a description
field. The description
field is a string that can be used to describe the server. This is useful for providing additional information about the server, such as its location or purpose.
In our example, the description
field is used to describe the server as the staging server.
The third server object contains a url
field, a description
field, and a variables
field. The variables
field is an array of objects that define variables that can be used to construct the base URL.
In this example, the URL is a template string that contains two variables: organization
and environment
.
Each variable's name is defined by the object's key.
The default
field is a string that defines the default value for the variable.
The enum
field is an array of strings that define the possible values for the variable.
The description
field is a string that can be used to describe the variable. This is useful for providing additional information about the variable, such as its purpose.
This field is not used by the OpenAPI documentation generator, but it can be used by other tools to provide additional information to API users.
openapi: 3.1.0servers:- url: https://speakeasy.bar- description: The staging server. url: https://staging.speakeasy.bar- description: A per-organization and per-environment API. url: https://{organization}.{environment}.speakeasy.bar variables: environment: default: prod description: The environment name. Defaults to the production environment. enum: - prod - staging - dev organization: default: api description: The organization name. Defaults to a generic organization.info: contact: email: support@speakeasy.bar name: Speakeasy Support url: https://support.speakeasy.bar description: A secret underground bar that serves drinks to those in the know. summary: A bar that serves drinks. title: The Speakeasy Bar version: 1.0.0components: schemas: APIError: properties: code: title: Code type: string details: title: Details type: object message: title: Message type: string title: APIError type: object AuthenticatePostRequest: properties: password: title: Password type: string username: title: Username type: string title: AuthenticatePostRequest type: object AuthenticatePostResponse: properties: token: title: Token type: string title: AuthenticatePostResponse type: object Drink: properties: name: description: The name of the drink. examples: - Old Fashioned - Manhattan - Negroni title: Name type: string price: description: The price of one unit of the drink in US cents. examples: - 1000 - 1200 - 1500 title: Price type: number productCode: description: The product code of the drink, only available when authenticated. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string stock: description: The number of units of the drink in stock, only available when authenticated. title: Stock type: integer type: $ref: '#/components/schemas/DrinkType' required: - name - price title: Drink type: object DrinkType: description: An enumeration. enum: - cocktail - non-alcoholic - beer - wine - spirit - other title: DrinkType Error: properties: code: title: Code type: string message: title: Message type: string title: Error type: object Ingredient: properties: name: description: The name of the ingredient. examples: - Sugar Syrup - Angostura Bitters - Orange Peel title: Name type: string productCode: description: The product code of the ingredient, only available when authenticated. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string stock: description: The number of units of the ingredient in stock, only available when authenticated. examples: - 10 - 5 - 0 title: Stock type: integer type: $ref: '#/components/schemas/IngredientType' required: - name - type title: Ingredient type: object IngredientType: description: An enumeration. enum: - fresh - long-life - packaged title: IngredientType Order: properties: productCode: description: The product code of the drink or ingredient. examples: - AC-A2DF3 - NAC-3F2D1 - APM-1F2D3 title: Productcode type: string quantity: description: The number of units of the drink or ingredient to order. minimum: 1.0 title: Quantity type: integer status: allOf: - $ref: '#/components/schemas/Status' description: The status of the order. type: $ref: '#/components/schemas/OrderType' required: - type - productCode - quantity - status title: Order type: object OrderType: description: An enumeration. enum: - drink - ingredient title: OrderType Status: description: An enumeration. enum: - pending - processing - complete title: Status Webhook: description: An enumeration. enum: - stockUpdate title: Webhook WebhooksSubscribePostRequest: properties: url: title: Url type: string webhook: $ref: '#/components/schemas/Webhook' title: WebhooksSubscribePostRequest type: objectpaths: /authenticate: post: description: Authenticate with the API by providing a username and password. operationId: authenticate_authenticate_post requestBody: content: application/json: schema: $ref: '#/components/schemas/AuthenticatePostRequest' required: true responses: '200': content: application/json: schema: $ref: '#/components/schemas/AuthenticatePostResponse' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Authenticate tags: - authentication /drink/{name}: get: description: Get a drink. operationId: get_drink_drink__name__get parameters: - in: path name: name required: true schema: title: Name type: string responses: '200': content: application/json: schema: $ref: '#/components/schemas/Drink' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Get Drink tags: - drinks /drinks: get: description: Get a list of drinks. operationId: list_drinks_drinks_get parameters: - in: query name: type required: false schema: $ref: '#/components/schemas/DrinkType' responses: '200': content: application/json: schema: items: $ref: '#/components/schemas/Drink' title: Response List Drinks Drinks Get type: array description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: List Drinks tags: - drinks /ingredients: get: description: Get a list of ingredients. operationId: list_ingredients_ingredients_get requestBody: content: application/json: schema: items: type: string title: Ingredients type: array responses: '200': content: application/json: schema: items: $ref: '#/components/schemas/Ingredient' title: Response List Ingredients Ingredients Get type: array description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: List Ingredients tags: - ingredients /order: post: description: Create an order. operationId: create_order_order_post parameters: - in: query name: callback_url required: false schema: title: Callback Url type: string requestBody: content: application/json: schema: items: $ref: '#/components/schemas/Order' title: Body type: array required: true responses: '200': content: application/json: schema: $ref: '#/components/schemas/Order' description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Create Order tags: - orders /webhooks/subscribe: post: description: Subscribe to webhooks. operationId: subscribe_to_webhooks_webhooks_subscribe_post requestBody: content: application/json: schema: items: $ref: '#/components/schemas/WebhooksSubscribePostRequest' title: Body type: array required: true responses: '200': content: application/json: schema: {} description: Successful Response 5XX: content: application/json: schema: $ref: '#/components/schemas/APIError' description: Server Error default: content: application/json: schema: $ref: '#/components/schemas/Error' description: Default Response summary: Subscribe To Webhooks tags: - configuration
Steps to Adapt Swagger 2.0 URL Definitions to OpenAPI 3.x
-
Identify Swagger 2.0 URL Components: Extract the
host
,basePath
, andschemes
values from your Swagger 2.0 document. -
Create the servers array: Initiate a
servers
array in your OpenAPI 3.x document. -
Translate URL Components: For each scheme in your Swagger 2.0 document, create a
server
object in the OpenAPI 3.xservers
array. Combine thescheme
,host
, andbasePath
to form theurl
field of each server object.
For example, if your Swagger 2.0 document contains the following URL components:
swagger: "2.0"host: api.example.combasePath: /v1schemes: - https - http
You would create the following servers
array in your OpenAPI 3.x document:
openapi: 3.1.0servers: - url: https://api.example.com/v1 - url: http://api.example.com/v1
Best Practices for Defining Servers in OpenAPI
When defining servers in an OpenAPI document, it's crucial to strike a balance between flexibility and clarity. The goal is to provide enough information for users to understand and use the API effectively while allowing for various deployment scenarios.
Here are some best practices to keep in mind:
-
Provide clear and concise descriptions: When using the
description
field, ensure it clearly indicates the purpose or specific use case of each server. This is particularly helpful in multiserver setups where different servers serve different roles, such as development, staging, and production. -
Use variables judiciously: Variables offer great flexibility but can also introduce complexity. Use them sparingly and only when necessary, such as when users have unique base URLs or need to select a specific environment.
-
Document server variables thoroughly: If you use variables in your server URLs, provide clear documentation on what each variable represents and the valid values (
enum
) it can take. This documentation is crucial for users who need to understand how to construct the URLs correctly. -
Consider including common environment URLs: While variables offer flexibility, sometimes it's easier for users if you explicitly list common environments (like
production
,staging
,development
) as separate server entries. This approach reduces the need for users to understand and manipulate variables. -
Validate server URLs regularly: Use automated tools to validate that the URLs in the
servers
section are up to date and operational. This check is particularly important for APIs that undergo frequent changes or have multiple deployment environments. -
Stay consistent across documents: If you manage multiple OpenAPI documents, maintain consistency in how servers are defined across them. This consistency helps users who work with multiple APIs in your suite, making it easier to understand and switch between them.
By following these best practices, you can ensure that your OpenAPI server definitions are both functional and user-friendly, enhancing the overall usability and accessibility of your API.
Advanced Server Definitions: Using Variables
Server variables offer significant flexibility and adaptability when defining servers. This approach is especially useful in scenarios where the base URL of an API might change based on different environments (like production, staging, or development) or other factors (like user-specific or regional settings). Here's how to leverage variables effectively in your OpenAPI server definitions.
Understanding Variables in Server URLs
-
Defining variables: Variables in OpenAPI are defined within the
servers
array. Each server object can have avariables
field, which is an object itself. This object contains keys representing variable names, each with its set of properties. -
Properties of variables: The properties of a variable can include:
default
: A mandatory field that specifies the default value of the variable.enum
: An optional array of possible values the variable can take.description
: An optional field to describe the variable's purpose or usage.
-
Using variables in URLs: Variables are used within the
url
field of a server object, enclosed in curly braces{}
. For example,https://{environment}.api.example.com
.
Best Practices for Using Variables
-
Name variables clearly: Choose clear and descriptive names for your variables. Names like
environment
,region
, orversion
can be more intuitive for users to understand and use. -
Use sensible defaults: Always provide sensible default values that point to the most common or recommended server configuration. This approach ensures that the API can be used out of the box without requiring users to modify the server URL.
-
Restrict values with enums: When appropriate, use
enum
to restrict the values that a variable can take. This is particularly useful for environment variables where only specific values likeproduction
,staging
, anddevelopment
are valid. -
Descriptive documentation: Each variable should be accompanied by a description that explains its purpose and how it should be used. This is crucial for users who are unfamiliar with your API or its configuration options.
-
Test variable-driven URLs: Ensure that all combinations of variables and their values lead to valid and accessible API endpoints. This testing is critical to avoid configuration errors that could make the API unusable.
Example of a Variable-Driven Server Definition
openapi: 3.1.0servers: - url: https://{environment}.api.example.com/v1 description: API server - selectable environment variables: environment: default: production enum: - production - staging - development description: Deployment environment of the API
In this example, the environment
variable allows users to switch between different deployment environments without the need for separate server entries for each one.
Use variables in server definitions to enhance the flexibility and scalability of your API configurations, catering to a wide range of deployment scenarios and user needs.
Servers at the Path or Operation Level
While it's common to define servers at the global level in OpenAPI documents, there are cases where specifying servers at the path or operation level is essential. This approach allows for more granular control, enabling different parts of the API to interact with different servers. It's particularly useful in microservices architectures, where different services may reside on different servers, or when specific operations require a unique endpoint.
Overriding Servers at Path or Operation Level
-
Path-level servers: You can specify servers for individual paths. This is useful when different paths in your API are hosted on different servers. For instance, if your API handles file uploads and general data requests separately, you might have different servers handling each.
-
Operation-level servers: Similarly, servers can be specified for individual operations (GET, POST, PUT, DELETE, etc.). This granularity is beneficial when a specific operation, like a data submission (POST request), needs to be directed to a distinct server, like a secure data processing server.
Best Practices
-
Clear documentation: Clearly document why certain paths or operations use different servers. This clarity helps developers understand the API's architecture and its interaction with various servers.
-
Consistency in structure: If you have different servers for different paths or operations, maintain a consistent structure in how these are defined to avoid confusion.
-
Fallback to global servers: Ensure that there is always a fallback server defined at the global level. This fallback acts as a default in cases where a path or operation doesn't explicitly specify a server.
Example of a Server Definition at the Path Level
Consider an API where file uploads are handled by a dedicated server. Here's how you might define this at the path level:
paths: /upload: servers: - url: https://upload.api.example.com description: Dedicated server for file uploads post: summary: Upload a file # ... other operation details ...
In this example, any POST requests to the /upload
path would be directed to the specified upload server, differentiating it from other operations in the API that use the default global server.
By strategically using servers at the path or operation levels, you can effectively manage different aspects of your API's functionality, ensuring that each part interacts with the most appropriate server.
Case Studies: Effective Server Definitions in OpenAPI
We'll now look at a few examples of how different companies have used OpenAPI server definitions to enhance their APIs' usability and functionality.
Stripe: Path-Level Servers for File Uploads
Stripe's OpenAPI documentation offers an excellent example of using path-level servers. In the Stripe API, the endpoint for file uploads is directed to the https://files.stripe.com/
server, optimized for handling large data transfers. This separation ensures that the file upload process does not interfere with the regular API traffic and provides a more efficient way to handle resource-intensive operations.
The following excerpt from Stripe's OpenAPI document (opens in a new tab) illustrates this setup:
openapi: 3.0.0paths: /v1/files: post: operationId: PostFiles servers: - url: "https://files.stripe.com" # ... other operation details ...servers: - url: "https://api.stripe.com"
This setup demonstrates a clear understanding of operational requirements and a commitment to providing a seamless user experience.
Stripe's OpenAPI document could be further enhanced by providing a fallback global server in case the file server is unavailable and documenting the reason for using a separate server for file uploads.
Datadog: Dynamic Server Selection with Variables
Datadog's API, known for its scalability and flexibility, leverages variables in server definitions to allow users to select their preferred region. This feature is particularly useful for global services where latency and data residency are critical considerations.
This excerpt from Datadog's OpenAPI document (opens in a new tab) illustrates this setup.
openapi: 3.0.0servers: - url: https://{subdomain}.{site} variables: site: default: datadoghq.com description: The regional site for Datadog customers. enum: - datadoghq.com - us3.datadoghq.com - us5.datadoghq.com - ap1.datadoghq.com - datadoghq.eu - ddog-gov.com subdomain: default: api description: The subdomain where the API is deployed. - url: "{protocol}://{name}" variables: name: default: api.datadoghq.com description: Full site DNS name. protocol: default: https description: The protocol for accessing the API. - url: https://{subdomain}.{site} variables: site: default: datadoghq.com description: Any Datadog deployment. subdomain: default: api description: The subdomain where the API is deployed.paths: /api/v2/logs: post: operationId: SubmitLog servers: - url: https://{subdomain}.{site} variables: site: default: datadoghq.com description: The regional site for customers. enum: - datadoghq.com - us3.datadoghq.com - us5.datadoghq.com - ap1.datadoghq.com - datadoghq.eu - ddog-gov.com subdomain: default: http-intake.logs description: The subdomain where the API is deployed. - url: "{protocol}://{name}" variables: name: default: http-intake.logs.datadoghq.com description: Full site DNS name. protocol: default: https description: The protocol for accessing the API. - url: https://{subdomain}.{site} variables: site: default: datadoghq.com description: Any Datadog deployment. subdomain: default: http-intake.logs description: The subdomain where the API is deployed.
In this example, users can dynamically choose the region closest to them, enhancing the performance and reliability of the API.
openapi: 3.0.0servers: - url: https://{subdomain}.{site} variables: site: default: datadoghq.com description: The regional site for Datadog customers. enum: - datadoghq.com - us3.datadoghq.com - us5.datadoghq.com - ap1.datadoghq.com - datadoghq.eu - ddog-gov.com subdomain: default: api description: The subdomain where the API is deployed. - url: "{protocol}://{name}" variables: name: default: api.datadoghq.com description: Full site DNS name. protocol: default: https description: The protocol for accessing the API. - url: https://{subdomain}.{site} variables: site: default: datadoghq.com description: Any Datadog deployment. subdomain: default: api description: The subdomain where the API is deployed.paths: /api/v2/logs: post: operationId: SubmitLog servers: - url: https://{subdomain}.{site} variables: site: default: datadoghq.com description: The regional site for customers. enum: - datadoghq.com - us3.datadoghq.com - us5.datadoghq.com - ap1.datadoghq.com - datadoghq.eu - ddog-gov.com subdomain: default: http-intake.logs description: The subdomain where the API is deployed. - url: "{protocol}://{name}" variables: name: default: http-intake.logs.datadoghq.com description: Full site DNS name. protocol: default: https description: The protocol for accessing the API. - url: https://{subdomain}.{site} variables: site: default: datadoghq.com description: Any Datadog deployment. subdomain: default: http-intake.logs description: The subdomain where the API is deployed.
The site
variable allows users to select the regional site for Datadog customers.
openapi: 3.0.0servers: - url: https://{subdomain}.{site} variables: site: default: datadoghq.com description: The regional site for Datadog customers. enum: - datadoghq.com - us3.datadoghq.com - us5.datadoghq.com - ap1.datadoghq.com - datadoghq.eu - ddog-gov.com subdomain: default: api description: The subdomain where the API is deployed. - url: "{protocol}://{name}" variables: name: default: api.datadoghq.com description: Full site DNS name. protocol: default: https description: The protocol for accessing the API. - url: https://{subdomain}.{site} variables: site: default: datadoghq.com description: Any Datadog deployment. subdomain: default: api description: The subdomain where the API is deployed.paths: /api/v2/logs: post: operationId: SubmitLog servers: - url: https://{subdomain}.{site} variables: site: default: datadoghq.com description: The regional site for customers. enum: - datadoghq.com - us3.datadoghq.com - us5.datadoghq.com - ap1.datadoghq.com - datadoghq.eu - ddog-gov.com subdomain: default: http-intake.logs description: The subdomain where the API is deployed. - url: "{protocol}://{name}" variables: name: default: http-intake.logs.datadoghq.com description: Full site DNS name. protocol: default: https description: The protocol for accessing the API. - url: https://{subdomain}.{site} variables: site: default: datadoghq.com description: Any Datadog deployment. subdomain: default: http-intake.logs description: The subdomain where the API is deployed.
The enum
field restricts the possible values to the available regional sites.
openapi: 3.0.0servers: - url: https://{subdomain}.{site} variables: site: default: datadoghq.com description: The regional site for Datadog customers. enum: - datadoghq.com - us3.datadoghq.com - us5.datadoghq.com - ap1.datadoghq.com - datadoghq.eu - ddog-gov.com subdomain: default: api description: The subdomain where the API is deployed. - url: "{protocol}://{name}" variables: name: default: api.datadoghq.com description: Full site DNS name. protocol: default: https description: The protocol for accessing the API. - url: https://{subdomain}.{site} variables: site: default: datadoghq.com description: Any Datadog deployment. subdomain: default: api description: The subdomain where the API is deployed.paths: /api/v2/logs: post: operationId: SubmitLog servers: - url: https://{subdomain}.{site} variables: site: default: datadoghq.com description: The regional site for customers. enum: - datadoghq.com - us3.datadoghq.com - us5.datadoghq.com - ap1.datadoghq.com - datadoghq.eu - ddog-gov.com subdomain: default: http-intake.logs description: The subdomain where the API is deployed. - url: "{protocol}://{name}" variables: name: default: http-intake.logs.datadoghq.com description: Full site DNS name. protocol: default: https description: The protocol for accessing the API. - url: https://{subdomain}.{site} variables: site: default: datadoghq.com description: Any Datadog deployment. subdomain: default: http-intake.logs description: The subdomain where the API is deployed.
Datadog also uses operation-level servers to direct log uploads to the appropriate server.
openapi: 3.0.0servers: - url: https://{subdomain}.{site} variables: site: default: datadoghq.com description: The regional site for Datadog customers. enum: - datadoghq.com - us3.datadoghq.com - us5.datadoghq.com - ap1.datadoghq.com - datadoghq.eu - ddog-gov.com subdomain: default: api description: The subdomain where the API is deployed. - url: "{protocol}://{name}" variables: name: default: api.datadoghq.com description: Full site DNS name. protocol: default: https description: The protocol for accessing the API. - url: https://{subdomain}.{site} variables: site: default: datadoghq.com description: Any Datadog deployment. subdomain: default: api description: The subdomain where the API is deployed.paths: /api/v2/logs: post: operationId: SubmitLog servers: - url: https://{subdomain}.{site} variables: site: default: datadoghq.com description: The regional site for customers. enum: - datadoghq.com - us3.datadoghq.com - us5.datadoghq.com - ap1.datadoghq.com - datadoghq.eu - ddog-gov.com subdomain: default: http-intake.logs description: The subdomain where the API is deployed. - url: "{protocol}://{name}" variables: name: default: http-intake.logs.datadoghq.com description: Full site DNS name. protocol: default: https description: The protocol for accessing the API. - url: https://{subdomain}.{site} variables: site: default: datadoghq.com description: Any Datadog deployment. subdomain: default: http-intake.logs description: The subdomain where the API is deployed.
This excerpt from Datadog's OpenAPI document (opens in a new tab) illustrates this setup.
In this example, users can dynamically choose the region closest to them, enhancing the performance and reliability of the API.
The site
variable allows users to select the regional site for Datadog customers.
The enum
field restricts the possible values to the available regional sites.
Datadog also uses operation-level servers to direct log uploads to the appropriate server.
openapi: 3.0.0servers: - url: https://{subdomain}.{site} variables: site: default: datadoghq.com description: The regional site for Datadog customers. enum: - datadoghq.com - us3.datadoghq.com - us5.datadoghq.com - ap1.datadoghq.com - datadoghq.eu - ddog-gov.com subdomain: default: api description: The subdomain where the API is deployed. - url: "{protocol}://{name}" variables: name: default: api.datadoghq.com description: Full site DNS name. protocol: default: https description: The protocol for accessing the API. - url: https://{subdomain}.{site} variables: site: default: datadoghq.com description: Any Datadog deployment. subdomain: default: api description: The subdomain where the API is deployed.paths: /api/v2/logs: post: operationId: SubmitLog servers: - url: https://{subdomain}.{site} variables: site: default: datadoghq.com description: The regional site for customers. enum: - datadoghq.com - us3.datadoghq.com - us5.datadoghq.com - ap1.datadoghq.com - datadoghq.eu - ddog-gov.com subdomain: default: http-intake.logs description: The subdomain where the API is deployed. - url: "{protocol}://{name}" variables: name: default: http-intake.logs.datadoghq.com description: Full site DNS name. protocol: default: https description: The protocol for accessing the API. - url: https://{subdomain}.{site} variables: site: default: datadoghq.com description: Any Datadog deployment. subdomain: default: http-intake.logs description: The subdomain where the API is deployed.
Conclusion: The Impact of Well-Defined Servers in API Usability
The way servers are defined in OpenAPI documents can significantly impact the usability and effectiveness of an API. Well-defined servers provide clear, accessible endpoints for different operational needs, improve the developer experience, and foster trust in the API's reliability and efficiency. Key benefits include:
- Enhanced clarity: Clear server definitions help developers understand where and how to interact with the API.
- Operational flexibility: Using variables and specifying servers at different levels (global, path, and operation) allows for greater operational flexibility and efficiency.
- Improved performance: Strategic server allocation, such as dedicated endpoints for resource-intensive tasks, optimizes API performance.
- Global scalability: Variables that allow for regional server selection make the API more adaptable to global users, addressing concerns like latency and data residency.
Additional Resources and Tools for OpenAPI Server Definition
If you're interested in deepening your understanding of OpenAPI server definitions, we recommend the following resources and tools:
- OpenAPI Specification: The official OpenAPI Specification (opens in a new tab) documentation provides comprehensive guidance on server definitions and other aspects of OpenAPI.
- Swagger Editor: An online tool that helps visualize and edit OpenAPI documents (opens in a new tab), making it easier to define and review server configurations.
- The OpenAPI Specification Explained: API Servers: A detailed guide to the OpenAPI Servers (opens in a new tab) that explains the different aspects of server definitions and how to use them effectively.
- Speakeasy documentation: Our documentation on how to configure your servers (opens in a new tab) in OpenAPI while creating SDKs with Speakeasy.