Recently, I’ve been looking into AsyncAPI, an open-source specification and tools to document and maintain event-driven architectures (EDAs).
In this blog post, I want summarize the basics of AsyncAPI and point to some useful links to learn more. In future blog posts, I’ll get into more details of AsyncAPI.
AsyncAPI: Why? What?
AsyncAPI is an open source initiative with the goal of making event-driven APIs as easy as REST APIs. Fundamentally, it is a specification to define asynchronous APIs, similar to what OpenAPI (aka Swagger) does for REST APIs.
AsyncAPI also provides tools to visualize and validate AsyncAPI specs and generators to generate code from the spec for various languages and frameworks.
Specs and schemas
You can see all the previous and current specs of AsyncAPI. Specs for the latest and pre-release versions:
- 2.6.0 Spec: The latest official spec.
- 3.0.0 Spec: The in-progress pre-release spec.
You can also validate the AsyncAPI documents with the AsyncAPI JSON Schema definitions. Schema for the latest version:
Concepts
These are the main concepts in AsyncAPI:
-
Server: An infrastructure that receives messages and delivers them to those interested. They often store messages until delivered. Examples are Google Cloud, RabbitMQ, Apache Kafka, Solace, etc.
-
Channel: An addressable component created by the server to organize transmission of messages between producers and consumers. Channels can be defined as a topic, queue, routing key, path, or subject depending on the protocol used.
-
Protocol: How information is exchanged between applications and channels such as AMQP, HTTP, WebSocket, JMS, Kafka, MQTT etc.
-
Application: A producer or a consumer that support the selected protocol to exchange messages with the server.
-
Producer (Publisher): An application that sends messages to a channel.
-
Consumer (Subscriber): An application that consumes for messages from a channel.
-
Message: Mechanism to exchange information between servers and applications via a channel serialized in the format specified by the protocol. It can support multiple patterns such as event (to communicate that a fact has occurred), command (to instruct subscriber to do something), request or response.
-
Binding: Server, channel, operation, and messaging bindings allow protocol-specific information, e.g.
Google Cloud Pub/Sub Server Binding
,Google Cloud Pub/Sub Channel Binding
,Google Cloud Pub/Sub Operation Binding
,Google Cloud Pub/Sub Message Binding
.
OpenAPI vs. AsyncAPI
If you’re coming from OpenAPI and you want to see how it compares to AsyncAPI, here’s a nice diagram from the AsyncAPI docs.
How does an AsyncAPI spec look like?
hello-world1.yaml
is the simplest AsyncAPI definition possible. It’s an application that has a single hello
channel. Users can publish messages to this channel and the message payload is
simply a string.
# The simplest AsyncAPI spec possible
asyncapi: 2.6.0
info:
title: Hello world application
version: '0.1.0'
channels:
hello:
publish:
message:
payload:
type: string
hello-world2.yaml is a more complicated AsyncAPI definition with servers, channels, components and schemas.
# Slightly more complicated AsyncAPI with servers, channels, components,
# and schemas
asyncapi: 2.6.0
info:
title: Hello world application
version: 0.1.0
# You can have multiple servers for production, staging, test, etc.
servers:
production:
url: broker.mycompany.com
protocol: amqp
description: This is "My Company" broker.
# Each channel is part of a server. If a channel does not specify a server,
# it's available on all servers.
channels:
hello:
# Publish means a user can publish messages to a channel
# Another option is subscribe
publish:
message:
# Message schema can be referenced
$ref: '#/components/messages/hello-msg'
goodbye:
publish:
message:
$ref: '#/components/messages/goodbye-msg'
components:
messages:
hello-msg:
# Message payload can be inlined for referenced
payload:
type: object
properties:
name:
type: string
sentAt:
$ref: '#/components/schemas/sent-at'
goodbye-msg:
payload:
type: object
properties:
sentAt:
$ref: '#/components/schemas/sent-at'
schemas:
# Schemas can be shared across payloads
sent-at:
type: string
description: The date and time a message was sent.
format: datetime
Publish vs. Subscribe semantics in AsyncAPI
In a channel, you can have publish
and subscribe
operations. This can be
confusing, depending on which perspective you’re considering (server vs. user)
and what you’re comparing against (eg. WebSocket).
AsyncAPI Term | WebSocket Term | From Server Perspective | From User Perspective |
---|---|---|---|
Publish | Send | The server receives the message | The user publishes/sends the message to the server |
Subscribe | Receive | The server publishes the message | The user subscribes/receives the message from the server |
It’s most useful to think of publish
and subscribe
from user’s perspective. You can read Demystifying the Semantics of Publish and
Subscribe for more
details.
Tools
These are some of the useful tools for AsyncAPI:
- AsyncStudio: Browser based tool to author and visualize and validate AsyncAPI files.
- AsyncAPI CLI: CLI based tool to work with AsyncAPI files.
- AsyncAPI Generator: A number of code generators for various languages and frameworks.
AsyncStudio is especially useful tool to author, visualize and validate AsyncAPI files. Here’s the previous sample visualized in AsyncStudio:
Samples
AsyncAPI has some basic samples in spec/examples folder.
More samples in my asyncapi-basics repo:
- hello-asyncapi - HelloWorld samples for AsyncAPI.
- quickstart - Shows how to generate an AsyncAPI spec, validate it and generate code from it using AsyncAPI tools.
- account-email-services - Show how to author an AsyncAPI spec for a simple 2 microservices architecture.
- account-service-cloudevent - Shows AsyncAPI specs for a service that accepts CloudEvents in binary and structured formats.
- google-pubsub - Shows AsyncAPI spec for Google Cloud Pub/Sub.
References
These are some references that you might find useful:
- AsyncAPI Basics
- AsyncAPI home
- AsyncAPI GitHub
- AsyncAPI Spec
- AsyncAPI Spec Examples
- Demystifying the Semantics of Publish and Subscribe
- Understanding AsyncAPIs with a Practical Example
- Simulating CloudEvents with AsyncAPI and Microcks
This wraps up our initial discussion of AsyncAPI. In future blog posts, I’ll look into some of the samples in more detail and show you what AsyncAPI can do for your EDA applications.