What is OpenAPI?

OpenAPI is a YAML / JSON specification for describing the surface area of web APIs.

openapi: 3.0.0
info:
 title: mBIP Application API
 description: This is an API for managing applications on the modular Big IP platform.
 version: 1.0.0
servers:
 - url: 'https://localhost:5443'
paths:
 '/icontrol/v1/applications/{application_id}':
  put:
   tags:
    - Application
   responses:
    '204':
     description: App PUT success
   parameters:
    - name: application_id
     in: path
     schema:
      type: string
     required: true
   requestBody:
    content:
     application/json:
      schema:
       $ref: '#/components/schemas/application'
    x-parameter-index: 1
  patch:
   tags:
    - Application
   responses:
    '204':
     description: App PATCH success
   parameters:
    - name: id
     in: path
     schema:
      type: string
     required: true
   requestBody:
    content:
     application/json:
      schema:
       $ref: '#/components/schemas/application'
    x-parameter-index: 1
  get:
   tags:
    - Application
   responses:
    '200':
     description: App model instance
     content:
      application/json:
       schema:
        $ref: '#/components/schemas/application'
   parameters:
    - name: id
     in: path
     schema:
      type: string
     required: true
  delete:
   tags:
    - Application
   responses:
    '204':
     description: App DELETE success
   parameters:
    - name: id
     in: path
     schema:
      type: string
     required: true
 /icontrol/v1/applications:
  post:
   x-controller-name: Application
   x-operation-name: create
   tags:
    - Application
   responses:
    '200':
     description: App model instance
     content:
      application/json:
       schema:
        $ref: '#/components/schemas/application'
    '400':
     description: oren haia po
   requestBody:
    content:
     application/json:
      schema:
       $ref: '#/components/schemas/application'
  patch:
   tags:
    - Application
   responses:
    '200':
     description: App PATCH success count
     content:
      application/json:
       schema:
        type: object
        properties:
         count:
          type: number
   parameters:
    - name: where
     in: query
     style: deepObject
     explode: true
     schema:
      type: object
   requestBody:
    content:
     application/json:
      schema:
       $ref: '#/components/schemas/application'
  get:
   tags:
    - Application
   responses:
    '200':
     description: Array of App model instances
     content:
      application/json:
       schema:
        type: array
        items:
         $ref: '#/components/schemas/application'
   parameters:
    - name: filter
     in: query
     style: deepObject
     explode: true
     schema:
      properties:
       where:
        type: object
       fields:
        type: object
        items:
         $ref: "#/components/schemas/fields"
       offset:
        type: integer
        minimum: 0
       limit:
        type: integer
        minimum: 0
       skip:
        type: integer
        minimum: 0
       order:
        type: array
        items:
         type: string
       include:
        type: array
        items:
         $ref: "#/components/schemas/include"
 /icontrol/v1/applications/count:
  get:
   summary: Application Count
   parameters:
    - name: where
     in: query
     style: deepObject
     explode: true
     schema:
      type: object
   tags:
    - Applications
   responses:
    '200':
     description: A successful response.
     content:
      application/json:
       schema:
        $ref: "#/components/schemas/appCount"
components:
 schemas:
  application:
   title: App
   properties:
    id:
     type: string
     description: Application ID
    name:
     type: string
    selfLink:
     type: string
  appCount:
   type: object
   properties:
    count:
     type: number
  include:
   type: object
   properties:
    relation:
     type: string
    scope:
     properties:
      where:
       type: object
      fields:
       type: object
       properties: {}
      offset:
       type: integer
       minimum: 0
      limit:
       type: integer
       minimum: 0
      skip:
       type: integer
       minimum: 0
      order:
       type: array
       items:
        type: string
  fields:
   properties:
    id:
     type: boolean
    name:
     type: boolean
    selfLink:
     type: boolean

Let's break down what that means!

OpenAPI Information Collection

One of the initial building blocks for any OpenAPI is the info collection, providing a coherent title description of the value an API delivers, as well as the version.

openapi: 3.0.0
info:
 title: mBIP Application API
 description: This is an API for managing applications on the modular Big IP platform.
 version: 1.0.0

Schema

Next, very OpenAPI begins with defining the schema that will be used as part of each API request and response, defining how data is passed back and forth.

schemas:
  application:
    properties:
      id:
        type: string
      name:
        type: string

JSON Schema

OpenAPI uses JSON Schema to define not only the schema used for each API, but it also can be used to validate each request or response in real time or testing.

"$id": https://example.com/application.schema.json
"$schema": http://json-schema.org/draft-07/schema#
description: This is a description of an application object.
type: object
properties:
  id:
    type: string
  name:
    type: string
    pattern: "^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$"
  ranking:
    type: integer
    minimum: integer
    maximum: integer
required:
 - id  - name

OpenAPI Server Collection

Then there is a servers collection that allows localhost, mock, development, production servers to be listed for each API instance.

servers:
 - url: 'https://localhost:5443'
 - url: 'https://mock.apiserver:5443'
 - url: 'https://10.1.1.24:5443'

OpenAPI Paths Collection

With basic information, servers, and schema defined, the path collections allows for defining how requests will be made to each API.

 /icontrol/v1/applications:
  get:
   summary: Get Applications
   description: This allows you to get all applications.
   operationId: getApplication
   tags:
    - Application
   responses:
    '200':
     description: Array of App model instances
     content:
      application/json:
       schema:
        type: array
        items:
         $ref: '#/components/schemas/application'
   parameters:
    - name: filter
     in: query
     style: deepObject

OpenAPI Path - Methods

The OpenAPI path collections allows you to define different HTTP methods using GET, POST, PUT, PATCH, and DELETE.

 /icontrol/v1/applications:
  post:
   summary: Add Applications
   description: This allows you to add an application.
   operationId: addApplication
   tags:
    - Application
   responses:
    '200':
     description: App model instance
     content:
      application/json:
       schema:
        $ref: '#/components/schemas/application'
    '400':
     description: oren haia po
   requestBody:
    content:
     application/json:
      schema:
       $ref: '#/components/schemas/application'
  patch:
   tags:
    - Application
   responses:
    '200':
     description: App PATCH success count
     content:
      application/json:
       schema:
       $ref: '#/components/schemas/application'

OpenAPI Path - Details

For each path method, you can provide a variety of other details about the path that can be used in documentation and other tooling.

 /icontrol/v1/applications:
  get:
   summary: Get Applications
   description: This allows you to get all applications.
   operationId: getApplication
   tags:
    - Application

OpenAPI Path - Headers

For each path method, you can provide details of the headers that can be submitted as part of each API request

   parameters:
    - name: Accept-Language
     in: header
     schema:
      type: string

OpenAPI Path - Parameters

For each path method, you can provide details of the query and path parameters that are available for use as part of each API request.

   parameters:
    - name: filter
     in: query
     schema:
      properties:
       where:
        type: object
       fields:
        type: object
        items:
         $ref: "#/components/schemas/fields"
       offset:
        type: integer
        minimum: 0
       limit:
        type: integer
        minimum: 0
       skip:
        type: integer
        minimum: 0
       order:
        type: array
        items:
         type: string
       include:
        type: array

OpenAPI Path - Request Body

Another colleciton that is provided with each path is the request collection allowing you to define each request, and the underlying schema that should be submitted.

   requestBody:
    content:
     application/json:
      schema:
       $ref: '#/components/schemas/application'

OpenAPI Path - Response

Then you can also define the response for each API response, providing details of media type, and the schema that will be returned.

   responses:
    '200':
     description: App model instance
     content:
      application/json:
       schema:
        $ref: '#/components/schemas/application'

OpenAPI Path - Examples

You can also define examples of API requests and responses, which can be used in documentation and mocking of each API.

   responses:
    '200':
     description: App model instance
     content:
      application/json:
       schema:
        $ref: '#/components/schemas/application'
       example:
         id: 3d3883fa343
         name: Application Name

Working In Concert

All of these AsyncAPI building blocks work together to define the surface area of each API, detailing the capability it provides.

openapi: 3.0.0
info:
 title: mBIP Application API
 description: This is an API for managing applications on the modular Big IP platform.
 version: 1.0.0
servers:
 - url: 'https://localhost:5443'
paths:
 '/icontrol/v1/applications/{application_id}':
  put:
   tags:
    - Application
   responses:
    '204':
     description: App PUT success
   parameters:
    - name: application_id
     in: path
     schema:
      type: string
     required: true
   requestBody:
    content:
     application/json:
      schema:
       $ref: '#/components/schemas/application'
    x-parameter-index: 1
  patch:
   tags:
    - Application
   responses:
    '204':
     description: App PATCH success
   parameters:
    - name: id
     in: path
     schema:
      type: string
     required: true
   requestBody:
    content:
     application/json:
      schema:
       $ref: '#/components/schemas/application'
    x-parameter-index: 1
  get:
   tags:
    - Application
   responses:
    '200':
     description: App model instance
     content:
      application/json:
       schema:
        $ref: '#/components/schemas/application'
   parameters:
    - name: id
     in: path
     schema:
      type: string
     required: true
  delete:
   tags:
    - Application
   responses:
    '204':
     description: App DELETE success
   parameters:
    - name: id
     in: path
     schema:
      type: string
     required: true
 /icontrol/v1/applications:
  post:
   x-controller-name: Application
   x-operation-name: create
   tags:
    - Application
   responses:
    '200':
     description: App model instance
     content:
      application/json:
       schema:
        $ref: '#/components/schemas/application'
    '400':
     description: oren haia po
   requestBody:
    content:
     application/json:
      schema:
       $ref: '#/components/schemas/application'
  patch:
   tags:
    - Application
   responses:
    '200':
     description: App PATCH success count
     content:
      application/json:
       schema:
        type: object
        properties:
         count:
          type: number
   parameters:
    - name: where
     in: query
     style: deepObject
     explode: true
     schema:
      type: object
   requestBody:
    content:
     application/json:
      schema:
       $ref: '#/components/schemas/application'
  get:
   tags:
    - Application
   responses:
    '200':
     description: Array of App model instances
     content:
      application/json:
       schema:
        type: array
        items:
         $ref: '#/components/schemas/application'
   parameters:
    - name: filter
     in: query
     style: deepObject
     explode: true
     schema:
      properties:
       where:
        type: object
       fields:
        type: object
        items:
         $ref: "#/components/schemas/fields"
       offset:
        type: integer
        minimum: 0
       limit:
        type: integer
        minimum: 0
       skip:
        type: integer
        minimum: 0
       order:
        type: array
        items:
         type: string
       include:
        type: array
        items:
         $ref: "#/components/schemas/include"
 /icontrol/v1/applications/count:
  get:
   summary: Application Count
   parameters:
    - name: where
     in: query
     style: deepObject
     explode: true
     schema:
      type: object
   tags:
    - Applications
   responses:
    '200':
     description: A successful response.
     content:
      application/json:
       schema:
        $ref: "#/components/schemas/appCount"
components:
 schemas:
  application:
   title: App
   properties:
    id:
     type: string
     description: Application ID
    name:
     type: string
    selfLink:
     type: string
  appCount:
   type: object
   properties:
    count:
     type: number
  include:
   type: object
   properties:
    relation:
     type: string
    scope:
     properties:
      where:
       type: object
      fields:
       type: object
       properties: {}
      offset:
       type: integer
       minimum: 0
      limit:
       type: integer
       minimum: 0
      skip:
       type: integer
       minimum: 0
      order:
       type: array
       items:
        type: string
  fields:
   properties:
    id:
     type: boolean
    name:
     type: boolean
    selfLink:
     type: boolean

OpenAPI Components Collections

The components collections stores the schema used across each API response, but also centralizes examples, request bodies, responses, and other reusable components.

components:
 schemas:
  application:
   title: App
   properties:
    id:
     type: string
    name:
     type: string
 examples:
  name:
   value:
     id: 3d3883fa343
     name: Application Name
 responses:
  '200':
    description: App model instance
    content:
      application/json:
        schema:
          $ref: '#/components/schemas/application'

OpenAPI Vendor Extensions

If there isn't an existing collection that meets the needs of defining each API, vendor extensions can be defined to extend OpenAPI, and provide the values needed.

components:
 schemas:
  application:
   title: App
   properties:
    id:
     type: string
    x-uniqueId: true
    x-mappings:
     targetClass: virtual
     targetProperty: appName
    name:
     type: string

What Is AsyncAPI?

OpenAPI is for HTTP 1.1 request and response APIs, and AsyncAPI is for publish and subscribe, message, and event based APIs that use HTTP/2, and TCP as a transport.

asyncapi: '1.2.0'
 info:
  title: 'Traffic Management Microkernel (TMM) API'
  description: 'This is an API definition for the Traffic Management Microkernel (TMM) API which uses NATS'
  version: '1.0.0'

 baseTopic: icontrol.config

 servers:
  - url: {ip_address}:{port}
   scheme: tcp
   description: The default NATS location.
   variables:
    ip_address:
     description: The ip address or domain for the server.
     default: 'localhost'
    port:
     description: Secure connection (TLS) is available through port 4244.
     default: '4244'
     enum:
      - '4244'
      - '4245'

 topics:
  icontrol.config:
   parameters:
    - $ref: '#/components/parameters/config'
   publish:
    $ref: '#/components/messages/config'

 components:
  messages:
   config:
    summary: The message wrapper for the default message
    payload:
     $ref: "#/components/schemas/config"

  schemas:
   config:
    type: object
    properties:
    
     applications:
      $ref: "#/components/schemas/application"
      
     sslCertificatePairs:
      $ref: "#/components/schemas/sentAt"

   application:
    title: App
    properties:
     id:
      type: string
      description: Application ID
     name:
      type: string
    
   sslCertificatePair:
    title: SslCertificatePair
    properties:
     id:
      type: string
      description: SSL client certificate pair ID
     name:
      type: string
     certificateContent:
      type: string
     certificateKeyContent:
      type: string
     certificatePath:
      type: string
     certificateKeyPath:
      type: string
     selfLink:
      type: string
     sslProfileId:
      type: string

AsyncAPI - Info Collection

Like the OpenAPI specification, AsyncAPI has an info collection, providing a title, description, and versioning for the API.

asyncapi: '1.2.0'
 info:
  title: 'Traffic Management Microkernel (TMM) API'
  description: 'This is an API definition for the Traffic Management Microkernel (TMM) API which uses NATS'
  version: '1.0.0'

AsyncAPI - Server Collection

It also has a servers collection, but allows you to go beyond HTTP 1.1, and define HTTP/2, HTTP/3, and other transport protocols.

 servers:
  - url: {ip_address}:{port}
   scheme: tcp
   description: The default NATS location.
   variables:
    ip_address:
     description: The ip address or domain for the server.
     default: 'localhost'
    port:
     description: Secure connection (TLS) is available through port 4244.
     default: '4244'
     enum:
      - '4244'
      - '4245'

AsyncAPI - Schema Collection

OpenAPI and AsyncAPI can both share schema across APIs defined within each specification, allowing for a shared JSON schema for use across all APIs being defined across the internal and external landscape.

 components:

  schemas:
   config:
    type: object
    properties:
    
     applications:
      $ref: "#/components/schemas/application"
      
     sslCertificatePairs:
      $ref: "#/components/schemas/sentAt"

   application:
    title: App
    properties:
     id:
      type: string
      description: Application ID
     name:
      type: string
    
   sslCertificatePair:
    title: SslCertificatePair
    properties:
     id:
      type: string
      description: SSL client certificate pair ID
     name:
      type: string
     certificateContent:
      type: string
     certificateKeyContent:
      type: string
     certificatePath:
      type: string
     certificateKeyPath:
      type: string
     selfLink:
      type: string
     sslProfileId:
      type: string

AsyncAPI - Messages Collection

Then AsncAPI gives you the ability to define the messages being passed back and forth, providing references to the shared schema being used.

 components:
  messages:
   config:
    summary: The message wrapper for the default message
    payload:
     $ref: "#/components/schemas/config"

AsyncAPI - Topics

Additionally you have the ability to define topics or subjects of messages that are being published or subscribed to via an API.

 topics:
  icontrol.config:
   parameters:
    - $ref: '#/components/parameters/config'
   publish:
    $ref: '#/components/messages/config'

AsyncAPI - Events

Beyond topics, events emitted from each API can be defined, providing a machine readable map of events being sent and received.

 events:
  received:
    - $ref: '#/components/parameters/config'
  sent:
    - $ref: '#/components/parameters/config'

AsyncAPI - Streams

AsyncAPI also has the ability to define streams of messages being made available through API being defined.

 stream:
  framing:
    type: "chunked"
    delimiter: "\r\n"
  read:
    - $ref: '#/components/parameters/heartbeat'
    - $ref: '#/components/parameters/config'

Working In Concert?

To define internal and external APIs that are using transport protocols beyond just HTTP 1.1, allowing schema, tags, and other components to shared between OpenAPI and AsyncAPI.

asyncapi: '1.2.0'
 info:
  title: 'Traffic Management Microkernel (TMM) API'
  description: 'This is an API definition for the Traffic Management Microkernel (TMM) API which uses NATS'
  version: '1.0.0'

 baseTopic: icontrol.config

 servers:
  - url: {ip_address}:{port}
   scheme: tcp
   description: The default NATS location.
   variables:
    ip_address:
     description: The ip address or domain for the server.
     default: 'localhost'
    port:
     description: Secure connection (TLS) is available through port 4244.
     default: '4244'
     enum:
      - '4244'
      - '4245'

 topics:
  icontrol.config:
   parameters:
    - $ref: '#/components/parameters/config'
   publish:
    $ref: '#/components/messages/config'

 components:
  messages:
   config:
    summary: The message wrapper for the default message
    payload:
     $ref: "#/components/schemas/config"

  schemas:
   config:
    type: object
    properties:
    
     applications:
      $ref: "#/components/schemas/application"
      
     sslCertificatePairs:
      $ref: "#/components/schemas/sentAt"

   application:
    title: App
    properties:
     id:
      type: string
      description: Application ID
     name:
      type: string
    
   sslCertificatePair:
    title: SslCertificatePair
    properties:
     id:
      type: string
      description: SSL client certificate pair ID
     name:
      type: string
     certificateContent:
      type: string
     certificateKeyContent:
      type: string
     certificatePath:
      type: string
     certificateKeyPath:
      type: string
     selfLink:
      type: string
     sslProfileId:
      type: string

AsyncAPI Components Collections

As with OpenAPI, AsyncAPI allows for elements to be stored in a centralized components collection for organiation and reuse.

 components:
  messages:
   config:
    summary: The message wrapper for the default message
    payload:
     $ref: "#/components/schemas/config"

  schemas:
   config:
    type: object
    properties:
    
     applications:
      $ref: "#/components/schemas/application"
      
     sslCertificatePairs:
      $ref: "#/components/schemas/sentAt"

   application:
    title: App
    properties:
     id:
      type: string
      description: Application ID
     name:
      type: string
    
   sslCertificatePair:
    title: SslCertificatePair
    properties:
     id:
      type: string
      description: SSL client certificate pair ID
     name:
      type: string
     certificateContent:
      type: string
     certificateKeyContent:
      type: string
     certificatePath:
      type: string
     certificateKeyPath:
      type: string
     selfLink:
      type: string
     sslProfileId:
      type: string

AsyncAPI - Vendor Extensions

If there isn't an existing collection that meets the needs of defining each API, vendor extensions can be defined to extend OpenAPI, and provide the values needed.

components:
 schemas:
  application:
   title: App
   properties:
    id:
     type: string
    x-uniqueId: true
    x-mappings:
     targetClass: virtual
     targetProperty: appName
    name:
     type: string

Why Use OpenAPI & AsyncAPI & JSON Schema?

There are many reasons for having a common way of specifying how APIs do what they do internally and externally, let's explore a handful of direct benefits.

Deployment...

OpenAPI, AsyncAPI, and JSON Schema delivers a declaritive format that developers can be used to deploy APIs with the gateway.

Documentation...

OpenAPI, AsyncAPI, and JSON Schema provide consistent, dynamically generated, but rich documentation for internal and external usage.

Testing...

OpenAPI, AsyncAPI, and JSON Schema provide what is needed to be able to sufficiently test and validate the surface area of APIs.

Performance...

OpenAPI, AsyncAPI, and JSON Schema provide what is needed to set the baseline performance for all APIs that are being deployed.

Security...

OpenAPI, AsyncAPI, and JSON Schema provide what is needed to properly scan and secure the entire surface area of the API.

Clients...

OpenAPI, AsyncAPI, and JSON Schema allow for easy use of APIs using API clients like Postman, PAW, and others.

Command Line Interface (CLI)...

OpenAPI, AsyncAPI, and JSON Schema define the scaffolding for deployment of command line interfaces that are in sync with the APIs.

Code...

OpenAPI, AsyncAPI, and JSON Schema provide what is needed to deliver generate client side code in a variety of programming languages.

Versioning...

OpenAPI, AsyncAPI, and JSON Schema provide the ability to version each individual OpenAPI, AsyncAPI, JSON Schema, and the vendor extensions being applied.

Communication...

OpenAPI, AsyncAPI, and JSON Schema make it possible to communicate around what each API delivers, providing the building blocks for human and machine readable engagements.

Dependencies...

OpenAPI, AsyncAPI, and JSON Schema provide us an opportunity to connect the dots between how APIs are being consumed, and where dependencies exist.

Vocabulary...

OpenAPI, AsyncAPI, and JSON Schema offer a vocabulary for us to use when moving APIs forward across teams, using standards that external consumers are already using.

Capabilities.

OpenAPI, AsyncAPI, and JSON Schema gives us a way to define the capabilities that being defined across the entire API infrastructure that exists serving external and internal functions.

OpenAPI, AsyncAPI, and JSON Schema