AsyncAPI — Event-Driven API Specification Guide
In this tutorial, you'll learn about AsyncAPI. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
AsyncAPI is an open-source specification for describing event-driven APIs using a format similar to OpenAPI, enabling documentation and Code Generation for message-based systems like Kafka, RabbitMQ, and WebSocket.
What You'll Learn
By the end of this tutorial, you'll understand the AsyncAPI specification structure, how to define channels and messages, generate code from AsyncAPI files, and integrate event-driven documentation into your workflow.
Why AsyncAPI Matters
REST APIs have OpenAPI — a standard for documentation and Code Generation. Event-driven APIs had no equivalent until AsyncAPI. Without it, teams rely on outdated wikis and tribal knowledge. DodaTech's Durga Antivirus Pro uses AsyncAPI to document its threat event stream, ensuring SIEM partners can integrate without reverse-engineering message formats.
AsyncAPI Document Structure
flowchart TB
subgraph "AsyncAPI Document"
A["asyncapi: 2.6.0"] --> B["info: title, version"]
A --> C["servers: connection details"]
A --> D["channels: pub/sub paths"]
D --> E["subscribe: messages received"]
D --> F["publish: messages sent"]
E --> G["message: schema (JSON Schema)"]
F --> G
A --> H["components: reusable schemas"]
end
style A fill:#dbeafe,stroke:#2563eb
style D fill:#fef3c7,stroke:#f59e0b
Defining an AsyncAPI Specification
asyncapi: 2.6.0
info:
title: Threat Detection Events API
version: 1.0.0
description: Real-time threat event stream from Durga Antivirus Pro
servers:
kafka:
url: kafka.dodatech.com:9092
protocol: kafka
description: Production Kafka cluster
channels:
threat/detected:
subscribe:
summary: Fired when a new threat is detected
operationId: onThreatDetected
message:
$ref: '#/components/messages/ThreatEvent'
scan/completed:
subscribe:
summary: Fired when a file scan completes
operationId: onScanCompleted
message:
payload:
type: object
properties:
scan_id:
type: string
status:
type: string
enum: [clean, infected, suspicious]
duration_ms:
type: integer
components:
messages:
ThreatEvent:
headers:
type: object
properties:
correlationId:
type: string
format: uuid
payload:
type: object
required: [threat_id, severity, timestamp]
properties:
threat_id:
type: string
severity:
type: string
enum: [low, medium, high, critical]
threat_type:
type: string
file_hash:
type: string
timestamp:
type: string
format: date-time
Generating Code from AsyncAPI
npm install -g @asyncapi/generator
# Generate Node.js subscriber
asyncapi generate fromTemplate threat-events.yaml @asyncapi/nodejs-ws-template
# Generate HTML documentation
asyncapi generate fromTemplate threat-events.yaml @asyncapi/html-template -o docs/
Expected output:
Generator done.
Check out your shiny new generated files at /output/nodejs-ws-template/.
Consuming AsyncAPI Events with Node.js
const { Kafka } = require("kafkajs");
const Kafka = new Kafka({
clientId: "dodatech-SIEM",
brokers: ["Kafka.dodatech.com:9092"],
});
async function consumeThreats() {
const consumer = Kafka.consumer({ groupId: "SIEM-integration" });
await consumer.connect();
await consumer.subscribe({ topic: "threat/detected" });
await consumer.run({
eachMessage: async ({ topic, partition, message }) => {
const threat = JSON.parse(message.value.toString());
console.log(`Threat detected: ${threat.threat_id}`);
console.log(`Severity: ${threat.severity}`);
console.log(`Type: ${threat.threat_type}`);
},
});
}
consumeThreats().catch(console.error);
Output:
Threat detected: T-20260624-001
Severity: critical
Type: ransomware
Common Errors
1. Confusing Publish and Subscribe
In AsyncAPI, publish means the server publishes messages for clients to receive. subscribe means the server subscribes to messages from clients. Think from the server's perspective, not the client's.
2. Missing Message Schemas
Every channel operation should reference a message schema. Inline payloads work for simple cases, but reusable $ref components keep large specs maintainable.
3. Ignoring Server Definitions
Without server definitions, your spec is documentation-only. Add protocol, URL, and security details so tooling can generate working clients.
4. Not Versioning Event Schemas
Message schemas evolve. Use semantic versioning for your AsyncAPI spec and maintain previous versions for backward compatibility.
5. Overlooking Headers
Correlation IDs, message types, and timestamps belong in headers, not the payload. Define headers separately in the message object.
Practice Questions
1. What problem does AsyncAPI solve?
AsyncAPI provides a standard way to document event-driven APIs (Kafka, Mqtt, WebSocket, AMQP), similar to how OpenAPI documents REST APIs. It enables automated documentation, Code Generation, and validation.
2. What is the difference between publish and subscribe in AsyncAPI?
From the server's perspective: publish means the server publishes (sends) messages that clients can receive. subscribe means the server subscribes to (receives) messages from clients.
3. How do you reference reusable schemas in AsyncAPI?
Use the $ref keyword with JSON Reference syntax: $ref: '#/components/messages/ThreatEvent'. Components can include messages, schemas, security schemes, and parameters.
4. Challenge: Write an AsyncAPI spec for a WebSocket-based chat application with two channels — one for sending messages and one for receiving them. Include user authentication via API key and a message schema with sender, content, and timestamp.
Use a WebSocket server with send/message (publish) and receive/message (subscribe) channels. Define the API key under components.securitySchemes and apply it at the server level. The message schema should require sender, content, and timestamp fields.
Mini Project: AsyncAPI to React Dashboard
Generate a React event dashboard from an AsyncAPI spec using @asyncapi/react-template. The dashboard should display live threat events from the Kafka stream with filtering by severity and threat type.
FAQ
Related Concepts
What's Next
Master OpenAPI specification for REST APIs, then return to AsyncAPI for event-driven systems. Explore API gateways that handle both REST and event-driven traffic.
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro. Updated 2026-06-24.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro