Writing OpenAPI documents

This chapter describes how to write OpenAPI specifications and best practices.

7 minute read

OpenAPI specification support

Currently, OpenAPI flow-trigger supports the following specifications:

Note that OpenAPI 3.0 is the preferred standard for API Builder. All links in our documentation will be to this standard, unless there is a specific need to link to OpenAPI 2.0. If you are using OpenAPI 2.0, you should consider moving to 3.0, but if you choose to remain on 2.0, you may have to refer back to equivalent sections in 2.0.

Also note that OpenAPI 3.1 is currently not supported, but is on the roadmap.

Unsupported features

The following features are currently unsupported by the OpenAPI flow-trigger. While you can document them in your OpenAPI specifications, their use may not work as expected during runtime. Unless otherwise indicated, assume that this is the case.

  • OpenAPI 3 requestBody anyOf, oneOf, allOf, and not are only supported for application/json. All other media types are not supported.
  • OpenAPI 3 parameter content is currently not supported, and schema is required.
  • OpenAPI 3 link¹.
  • OpenAPI 3 callback¹.
  • OpenAPI 3 parameter media type encoding¹.
  • OpenAPI 3 discriminator.
  • OpenAPI 2 collectionFormat for tsv (tab separated value).
  • OpenAPI 2 collectionFormat array of items more than one level deep (i.e. does not support array of array items).
  • OpenAPI 2 collectionFormat pipes and ssv are not supported in cookie, formData, header, or path (only supported in query).
  • multipart/form-data with arrays of binary data is not supported, e.g. curl -F file[]=a -F file[]=b.
  • OpenAPI 3.0 byte format¹ is supported, but it will not automatically decode the base64 data.
  • OpenAPI 3.0 base64 format is not supported. use byte instead.
  • OpenAPI 3 cookie parameters for objects and arrays, style="form", explode=true style is not supported.
  • In API Doc & Test, APIs with multipart/form-data or application/x-www-form-urlencoded bodies will fail to render examples and execute correctly if the body schema is missing an implicit type: object.
  • Media-type parameters such as ;charset=utf-8 in request and response are currently ignored.
  • OpenAPI response header styles.
  1. Using this feature in your OpenAPI specification will not cause any runtime issues, but using it may confuse clients.

JSON schema versions

OpenAPI 2.0 and 3.1 both effectively support a subset of JSON schema draft-04 with additional restrictions and formats. Though, OpenAPI 2.0 supports json-schema-draft-04, and OpenAPI 3.0 supports the Wright JSON schema, which is effectively draft-04 with some fixes (aka “json-schema-draft-05”).

When writing JSON schema, understand that you are more/less targeting draft-04 syntax, and not any of the other draft specifications.

JSON schema format support

The following formats are available for JSON schema validation:

JSON schema format Reference Validated
date JSON schema yes
time JSON schema yes
date-time JSON schema yes
uri JSON schema yes
uri-template JSON schema yes
url JSON schema yes
email JSON schema yes
hostname JSON schema yes
ipv4 JSON schema yes
ipv6 JSON schema yes
regex JSON schema yes
uuid JSON schema yes
json-pointer JSON schema yes
relative-json-pointer JSON schema yes
int32 OpenAPI yes
int64 OpenAPI yes
float OpenAPI no
double OpenAPI no
byte OpenAPI yes
binary OpenAPI no
password OpenAPI no

OpenAPI editors

At this time, API Builder does not have a UI for editing OpenAPI documents. We recommend using an external tool like Stoplight to create and manage your OpenAPI documents (API-first). It provides collaborative design, mocking, and revision history.

Writing OpenAPI documents

Before writing your own OpenAPI documents, you should be aware of the unsupported features. Also, have a look at our OpenAPI tips for ideas on how to write better OpenAPI specifications. The following sections provide technical details about how API Builder will interpret your OpenAPI specification.

API prefix

All API in API Builder are bound to a configurable apiPrefix path, which defaults to /api. Any path under the apiPrefix is protected by the configured authentication scheme in accessControl.apiPrefixSecurity, and will require that clients provided the requisite credentials in order to invoke the API.

Paths that are defined in your OpenAPI document, that are subsequently bound to flows, will be appended to the apiPrefix. For example, if your OpenAPI specification defines the path /users, it will be accessible from API Builder as /api/users.

Sometimes, having API bound to /api is not desirable from a client perspective. If all your designed paths begin with a common prefix, then by changing your apiPrefix in configuration to match the common prefix, API Builder will not apply the prefix twice, and the common prefix will be deduped. The following table illustrates.

OpenAPI example path(s) apiPrefix Bound API path(s) Deduped
/apple /api /api/apple no
/apple /fruits /fruits/apple no
/apple
/banana
/api /api/apple
/api/banana
no
/api/apple
/api/banana
/fruits /fruits/api/apple
/fruits/api/banana
no
/api/apple
/api/banana
/api /api/apple
/api/banana
yes

It is possible for paths to clash when also using Custom API, so on startup watch for warning messages. You should resolve path conflicts before going to production.

OpenAPI 2.0 basePath, host, and schemes

Any OpenAPI 2.0 fields basePath, host, and schemes in the specification will be ignored by API Builder and can be overridden.

Overriding servers, host, schemes, or basePath

There is a list of optional apidoc.overrides that you can specify as part of your service configuration that would allow you to tweak how the API specification is generated. This allows you to tweak specific OpenAPI values that are useful when the service is not consumed directly, such as when the services is exposed through a proxy. For example, you can change the defined OpenAPI servers, allowing the server URL(s) to be changed for different hosting environments, such as development, test, or production.

Use operationId

OpenAPI flow-trigger uses the operationId to uniquely identify operations, which are necessary when binding specific API operations to flows. While the operationId is optional in OpenAPI, we would recommend using it. If one is not provided, OpenAPI flow-trigger will generate one dynamically from the operation HTTP method and path (including path parameters), unnecessarily tightly couples the dynamically generated operationId to the operation. This can have an adverse affect of unbinding previously bound flows, if any of these properties change.

Using operationId has the following benefits:

  1. Allows you to change the HTTP method or path without any impact on previously bound flows.
  2. Useful as a short-hand identifier. For example, “getUserById” might be easier to communicate than “GET /organization/users/{userId}”
  3. Used when writing flow files to disk, so it provides a stronger connection to the API specification. Should any issues arises with a flow, they can be more easily traced back to the OpenAPI operation.

Security definitions are removed

OpenAPI flow-trigger will remove all security requirements, and security schemes from the entire OpenAPI specification. This is because API Builder has its own configurable authentication, and it will replace the security with its own.

Default error codes and responses

API Builder provides can return default errors and responses to the client that are not handled by the flow. Such errors can occur when the client makes a bad request, fails authentication, exceeds upload limits, or if an unexpected error occurred. It is recommended that you include the detail of all the potential errors, so that client developers know what to expect from the API. For convenience, a full specification of all the errors are listed below for convenience to use within your OpenAPI specifications.

components:
  schemas:
    AxwayError:
      type: object
      description: Axway error response.
      additionalProperties: true
      required:
        - success
        - message
      properties:
        id:
          description: A unique error code.
          type: string
        'request-id':
          description: A unique request identifier.
          type: string
          format: uuid
        success:
          description: A boolean indicating failure.
          type: boolean
          enum:
            - false
        code:
          description: The HTTP error code
          type: number
        message:
          description: A summary of the error
          type: string
        errors:
          description: An array of errors for additional context
          type: array
          items:
            type: string
            minLength: 1
  responses:
    BadRequest:
      description: Bad request
      content:
        application/json:
          schema:
            allOf:
            - $ref: '#/components/schemas/AxwayError'
            properties:
              code:
                type: number
                enum:
                  - 400
    Unauthorized:
      description: Unauthorized
      content:
        application/json:
          schema:
            allOf:
            - $ref: '#/components/schemas/AxwayError'
            properties:
              id:
                type: string
                enum:
                  - com.appcelerator.api.unauthorized
              code:
                type: number
                enum:
                  - 401
    NotFound:
      description: Bad request
      content:
        application/json:
          schema:
            allOf:
            - $ref: '#/components/schemas/AxwayError'
            properties:
              code:
                type: number
                enum:
                  - 404
    PayloadTooLarge:
      description: Bad request
      content:
        application/json:
          schema:
            allOf:
            - $ref: '#/components/schemas/AxwayError'
            properties:
              code:
                type: number
                enum:
                  - 413
    InternalServerError:
      description: Bad request
      content:
        application/json:
          schema:
            allOf:
            - $ref: '#/components/schemas/AxwayError'
            properties:
              code:
                type: number
                enum:
                  - 500

Path parameter names

OpenAPI path parameter names must be made up of characters containing only: A-Z a-z 0-9 _ according to Express route parameters guide.

Last modified April 8, 2022: staging (kabul) (#73) (577efb5)