Using Swagger Editor With AsyncAPI

Using Swagger Editor With AsyncAPI

Posted in

SmartBear recently announced that their popular open-source tool Swagger Editor now supports the AsyncAPI specification. This means you can now easily automate API creation, documentation, and testing for AsyncAPI services while keeping with the current best practices and standards.

This is great news for anyone developing or maintaining event-driven APIs. It’s also great news for developers using microservices, as AsyncAPI was created to address the needs of asynchronous communications.

With SmartBear’s announcement, API developers now have an easy path to working with AsyncAPI with a familiar tool. To help you make use of it, we’ve put together a guide on how to get started with SmartBear’s AsyncAPI editor.

How To Use Swagger Editor for AsyncAPI

Install Swagger Editor

To use SmartBear’s AsyncAPI, you’re going to need Swagger Editor. The first step in getting started with Swagger Editor for AsyncAPI is installing Swagger Editor.

There are numerous options for getting started with Swagger Editor. You can run it in your browser if you just want to try it out. You can also download the Swagger Editor code from GitHub if you’re going to run it locally.

Please note that if you’re running Swagger Editor in the browser, you’ll need to select the “Try our new Editor” option, by pressing the green button located in the top-right corner. The old Editor only supports Swagger and OpenAPI schemas.

If you want to try Swagger Editor with examples, templates, and UI all bundled together, you can sign up for a free trial of SwaggerHub. It lets you import or paste JSON files, view the API documentation directly, and even download the specifications as a YAML or JSON file. At the time of writing, Swagger Editor supports AsyncAPI 2.x.

Differences Between AsyncAPI and OpenAPI

Before we delve into our Swagger Editor for AsyncAPI in earnest, let’s take a quick look at the differences between the two formats. This will give a more complete understanding of what’s happening under the hood, so you’ll have an easier time implementing AsyncAPIs yourself.

AsyncAPI builds upon the OpenAPI specification, so there are many similarities between the two. Even better, AsyncAPI is compatible with OpenAPI schemas. AsyncAPI can also receive message payloads in any value, not just OpenAPI/AsyncAPI schemas. It can also accept Avro schema, for example.

The Async Server Object is nearly identical to the OpenAPI equivalent. The only difference is the scheme property is renamed protocol, and AsyncAPI introduces a new property called protocolVersion.

Another key difference between the two specifications is the difference between OpenAPI path parameters and AsyncAPI channel parameters. AsyncAPI doesn’t support “queries” or “cookies.” Header parameters can be defined in message objects, as well. This makes the AsyncAPI channel parameter the equivalent of OpenAPI path parameters.

For a more detailed breakdown, read our OpenAPI vs. AsyncAPI comparison article.

Creating an AsyncAPI “Hello World” Application

Now let’s put some of these ideas into practice by creating a basic AsyncAPI “Hello World” application. This will give you an example of these ideas in action, making them less conceptual and more concrete.

We’ll start by defining an application capable of receiving a “Hello {name}” message.

asyncapi: 2.5.0
info:
  title: Hello world application
  version: '0.1.0'
channels:
  hello:
    publish:
      message:
        payload:
          type: string
          pattern: '^hello .+$'

The first line details what version of AsyncAPI you’re using. In this version, we’re using AsyncAPI 2.5.0.

The info object contains the most pertinent info about an API, namely its title and version. It’s not mandatory, but it’s recommended that you create a new version anytime you make changes to the API.

The channels object details where the API receives messages from. Think of the analogy of a TV channel to make things more clear. When the channel is included in the channels section, the API is “subscribed” to that channel.

The payload defines what type of object the channel will accept and then specifies the format in which it will be returned.

To put this code into practical language, it reads: “This is the payload of the message that the Hello world application is subscribed to. You can publish the message to the hello channel, and the Hello world application will receive it.”

Creating a Real-World Use Case

Now let’s create an actual app to see AsyncAPI in action. We’re going to design a simple app for controlling a city’s streetlights.

Here’s the code:

asyncapi: '2.5.0'
info:
  title: Streetlights API
  version: '1.0.0'
  description: |
    The Smartylighting Streetlights API allows you
    to remotely manage the city lights.
  license:
    name: Apache 2.0
    url: 'https://www.apache.org/licenses/LICENSE-2.0'
servers:
  mosquitto:
    url: mqtt://test.mosquitto.org
    protocol: mqtt
channels:
  light/measured:
    publish:
      summary: Inform about environmental lighting conditions for a particular streetlight.
      operationId: onLightMeasured
      message:
        name: LightMeasured
        payload:
          type: object
          properties:
            id:
              type: integer
              minimum: 0
              description: Id of the streetlight.
            lumens:
              type: integer
              minimum: 0
              description: Light intensity measured in lumens.
            sentAt:
              type: string
              format: date-time
              description: Date and time when the message was sent.

The first chunk of code details what version of AsyncAPI you’re using, in this case, AsyncAPI 2.5.0. The info object defines the API’s name, Streetlights API, its version, 1.0.0, and a description of what it does and its license.

The channels section defines the event names the API will be publishing and those it subscribes to.

In this example, the Streetlights API subscribes to the light:measured channel. The operationID defines what function or method will perform this function. The payload property defines what the published events will look like.

      payload:
        type: object
        properties:
          id:
            type: integer
            minimum: 0
            description: Id of the streetlight.
          lumens:
            type: integer
            minimum: 0
            description: Light intensity measured in lumens.
          sentAt:
            type: string
            format: date-time
            description: Date and time when the message was sent.

The Payload objects are returned in the AsyncAPI schema.

In this example, this means that every event should contain an id; lumens, which must be greater than 0; and a sentAt property, which should contain a date and a time.

Final Thoughts on Using Swagger Editor for AsyncAPI

Having an IDE-like environment for creating, editing, and documenting AsyncAPI is incredibly powerful and valuable. Like with OpenAPI, it’s an important step towards standardization and widespread adoption.

It’s also beneficial for conceptualizing AsyncAPI. The streamlined real-time documentation alone will help you understand the necessary components that an AsyncAPI schema must possess. It helps take things from the abstract language of JSON objects into a more concrete and relatable form. Even more importantly, it makes explaining such concepts infinitely easier to non-programmers like clients and customers.

Considering that asynchronous communications and event-driven architecture are essential elements of modern microservices architecures, the time is right for widespread AsyncAPI adoption. Swagger Editor for AsyncAPI is a crucial step in that direction.