AsyncAPI: Event-getriebene APIs dokumentieren wie REST mit OpenAPI
AI generated
{ }
GET
AsyncAPI · Events · Messaging
AsyncAPI für event-getriebene APIs
Message-Queues und Event-Streams so systematisch dokumentieren wie REST-Endpoints mit OpenAPI

Sobald ein System asynchrone Nachrichten über RabbitMQ, Kafka oder WebSockets austauscht, fehlt eine Beschreibung wie OpenAPI: Welche Nachrichten fließen über welchen Kanal, in welchem Format, mit welcher Payload-Struktur. AsyncAPI schließt genau diese Lücke, mit einer Spezifikation, die sich bewusst an OpenAPI orientiert.

15 Min. Lesezeit AsyncAPI 3.0 · Channels Messaging · RabbitMQ · Kafka

1. Die Dokumentationslücke bei asynchronen APIs

OpenAPI hat sich für synchrone REST-Endpoints als verbindlicher Standard etabliert: Jeder Endpoint, jeder Parameter, jede Response-Struktur ist maschinenlesbar beschrieben. Sobald ein System stattdessen oder zusätzlich über Message-Queues, Event-Streams oder WebSocket-Kanäle kommuniziert, fehlt diese Beschreibung meist komplett. Neue Teammitglieder müssen den Quellcode der Consumer und Producer lesen, um herauszufinden, welche Nachrichten mit welcher Struktur über eine Queue laufen.

AsyncAPI überträgt das OpenAPI-Prinzip auf diese asynchrone Welt: eine Spezifikation, die Kanäle (Queues, Topics), die darüber ausgetauschten Nachrichten und deren Payload-Schema beschreibt, unabhängig vom konkreten Transportprotokoll. Die Syntax ist bewusst an OpenAPI angelehnt, sodass Teams, die bereits OpenAPI für REST nutzen, sich schnell zurechtfinden.

2. Die Grundstruktur einer AsyncAPI-Spezifikation

Eine AsyncAPI-Datei definiert Channels als zentrales Konzept, vergleichbar mit Pfaden in OpenAPI. Ein Channel repräsentiert eine Queue, ein Topic oder einen WebSocket-Kanal, über den Nachrichten fließen. Für jeden Channel wird beschrieben, ob er zum Senden (publish), Empfangen (subscribe) oder beides genutzt wird, aus Sicht der jeweiligen Anwendung. Die Trennung zwischen Channel-Definition (wo die Nachricht landet) und Operation-Definition (was eine bestimmte Anwendung damit tut) ist seit AsyncAPI 3.0 explizit, was Mehrdeutigkeiten aus früheren Versionen der Spezifikation auflöst.

Jede Nachricht referenziert ein Payload-Schema, das wie bei OpenAPI im JSON-Schema-Format definiert wird und damit wiederverwendbar und validierbar ist. Zusätzlich lassen sich Header, Correlation-IDs für Nachrichtenverfolgung und Beispiel-Payloads angeben, sodass ein neues Teammitglied allein aus der Spezifikation eine funktionierende Nachricht zusammenstellen kann. Wiederverwendbare Komponenten unter components/messages und components/schemas verhindern dabei, dass dieselbe Payload-Struktur an mehreren Stellen der Spezifikation redundant und potenziell inkonsistent definiert wird.


# order-events.asyncapi.yaml
asyncapi: 3.0.0
info:
  title: Order Events API
  version: 1.0.0
  description: Events rund um Bestell-Lifecycle in RabbitMQ

servers:
  production:
    host: rabbitmq.internal:5672
    protocol: amqp

channels:
  orderCreated:
    address: orders.created
    messages:
      orderCreatedMessage:
        $ref: '#/components/messages/OrderCreated'

operations:
  publishOrderCreated:
    action: send
    channel:
      $ref: '#/channels/orderCreated'

components:
  messages:
    OrderCreated:
      payload:
        type: object
        required: [orderId, customerId, totalAmount]
        properties:
          orderId:
            type: string
            format: uuid
          customerId:
            type: string
          totalAmount:
            type: number

3. Protokoll-Agnostik: ein Format für mehrere Transportwege

Ein wichtiger konzeptioneller Unterschied zu OpenAPI: AsyncAPI ist bewusst protokollunabhängig gestaltet. Dieselbe Grundstruktur beschreibt Kanäle über AMQP (RabbitMQ), Kafka, MQTT, WebSockets oder sogar HTTP-Webhooks, mit protokollspezifischen Bindings als zusätzliche, optionale Ergänzung pro Server und Channel.

Das ist besonders wertvoll für Systeme, die im Laufe der Zeit das Transportprotokoll wechseln oder mehrere Protokolle parallel nutzen, etwa RabbitMQ für interne Services und WebSockets für Live-Updates im Browser. Die fachliche Beschreibung der Nachrichten bleibt dabei stabil, nur die protokollspezifischen Bindings ändern sich, was einen Protokollwechsel deutlich risikoärmer macht als bei rein codebasierter Dokumentation ohne diese Trennung.

4. Codegenerierung: Consumer und Producer aus der Spezifikation ableiten

Wie bei OpenAPI existieren Generator-Tools (der AsyncAPI Generator), die aus einer Spezifikation Boilerplate-Code für Consumer und Producer in verschiedenen Sprachen erzeugen können, inklusive typisierter Payload-Klassen. Für PHP-Projekte ist das Ökosystem hier deutlich dünner als bei OpenAPI, weshalb die Spezifikation in der Praxis oft primär als Dokumentation statt als Codegen-Quelle dient.

Selbst ohne automatische Codegenerierung bleibt der Dokumentationswert hoch: Ein Symfony-Team kann die AsyncAPI-Spezifikation als verbindliche Referenz nutzen, um Payload-DTOs von Hand zu bauen, die dem beschriebenen Schema entsprechen, und in Contract-Tests gegen dieses Schema zu validieren. Ein solcher Contract-Test scheitert kontrolliert in der CI-Pipeline, sobald ein Producer versehentlich vom dokumentierten Schema abweicht, statt dass der Fehler erst produktiv bei einem stillschweigend fehlschlagenden Consumer auffällt.


<?php
// PHP: Payload-DTO passend zur AsyncAPI-Spezifikation
final readonly class OrderCreatedMessage
{
    public function __construct(
        public string $orderId,
        public string $customerId,
        public float $totalAmount,
    ) {
    }

    public static function fromArray(array $data): self
    {
        // Validierung gegen das in der AsyncAPI-Spec definierte Schema
        return new self(
            orderId: $data['orderId'],
            customerId: $data['customerId'],
            totalAmount: (float) $data['totalAmount'],
        );
    }
}

5. AsyncAPI Studio und visuelle Kanal-Übersicht

Das AsyncAPI Studio (analog zu Swagger UI bei OpenAPI) rendert eine Spezifikation als interaktive, durchsuchbare Dokumentation im Browser: alle Channels, Nachrichten und Schemas übersichtlich dargestellt, mit Beispiel-Payloads zum Aufklappen. Für Teams mit vielen Message-Typen über mehrere Queues hinweg ersetzt das den mühsamen Weg über verstreute Wiki-Seiten oder veraltete Diagramme. Das Studio lässt sich zudem lokal als Docker-Container betreiben oder direkt aus einem GitHub-Repository heraus statisch veröffentlichen, sodass externe Integratoren dieselbe Ansicht bekommen wie das eigene Team.

Zusätzlich lässt sich aus einer AsyncAPI-Spezifikation automatisch ein visuelles Architektur-Diagramm generieren, das zeigt, welche Services welche Kanäle publizieren und konsumieren. Das macht implizite Abhängigkeiten zwischen Services sichtbar, die sonst nur durch das Lesen mehrerer Codebasen erkennbar wären.

6. Versionierung und Breaking Changes bei Event-Schemas

Breaking Changes bei Event-Schemas sind tückischer als bei REST, weil es oft mehrere unabhängige Consumer gibt, die eine Nachricht verarbeiten, ohne dass der Producer weiß, wer im Detail zuhört. Eine entfernte oder umbenannte Property in einer Nachricht kann Consumer stillschweigend brechen, ohne dass der Fehler beim Publizieren selbst sichtbar wird, oft erst Tage später bei einer Fehleranalyse auffällt.

AsyncAPI-Spezifikationen sollten deshalb, genau wie OpenAPI-Spezifikationen, versioniert und in einem CI-Schritt auf Kompatibilität gegen die vorherige Version geprüft werden. Additive, abwärtskompatible Änderungen (neue optionale Felder) sind unkritisch, das Entfernen oder Umbenennen bestehender Felder erfordert eine neue Nachrichtenversion mit paralleler Übergangsphase.

7. AsyncAPI und OpenAPI in derselben Systemlandschaft kombinieren

Die meisten realen Systeme sind hybrid: synchrone REST-Endpoints für direkte Anfragen, asynchrone Events für Zustandsänderungen, die andere Services interessieren. Es gibt keinen Widerspruch darin, beide Spezifikationsformate parallel im selben Repository zu pflegen, jeweils für den Teil der API, für den sie gemacht sind.

Ein sinnvolles Muster ist, beide Spezifikationen im selben Dokumentations-Portal zu veröffentlichen, sodass ein externer Integrator an einer Stelle sowohl die REST-Endpoints als auch die relevanten Event-Kanäle findet, statt zwischen verschiedenen, unzusammenhängenden Dokumentationsquellen zu springen.

8. Praktischer Einstieg für ein bestehendes Symfony-Projekt

Der pragmatische Einstieg beginnt nicht mit einer vollständigen Spezifikation für alle bestehenden Queues, sondern mit einem einzigen, gut verstandenen Nachrichtentyp als Proof of Concept. Das Team lernt dabei die Syntax kennen und kann bewerten, ob der Dokumentationsaufwand im Verhältnis zum Nutzen steht, bevor die gesamte Event-Landschaft beschrieben wird. Ein guter Kandidat für diesen ersten Versuch ist ein Nachrichtentyp, der bereits mehrere unabhängige Consumer hat, weil dort der Dokumentationsnutzen am schnellsten spürbar wird.

Anschließend lohnt es sich, die Pflege der Spezifikation direkt an den Code zu koppeln, etwa durch eine CI-Prüfung, die bei einer Änderung am Message-Handler-Code auf eine fehlende Aktualisierung der AsyncAPI-Datei hinweist. Ohne diese Kopplung veraltet die Spezifikation erfahrungsgemäß genauso schnell wie unversionierte Wiki-Dokumentation.

9. AsyncAPI im Vergleich zu anderen Dokumentationsansätzen

Neben AsyncAPI gibt es weitere Wege, Event-Schemas zu dokumentieren, mit unterschiedlichen Kompromissen zwischen Aufwand, Tooling-Reife und Ausdrucksstärke.

Ansatz Tooling-Reife Protokoll-Abdeckung Typischer Einsatz
AsyncAPI Wachsend, gut für Doku AMQP, Kafka, MQTT, WebSocket Systematische Event-Dokumentation
Schema Registry (z.B. Confluent) Ausgereift für Kafka Primär Kafka Kafka-zentrierte Landschaften mit Avro/Protobuf
Handgeschriebenes Wiki Kein Tooling Beliebig Kleine Teams, wenige Message-Typen
Nur Code lesen Kein Tooling Beliebig Anti-Pattern, aber verbreiteter Ist-Zustand

Mironsoft

OpenAPI-Design, Symfony-APIs und API-Sicherheit

APIs, die externe Teams ohne Rückfragen integrieren können?

Wir prüfen bestehende REST-APIs auf inkonsistente Fehlerformate, fehlende OpenAPI-Dokumentation und Sicherheitslücken und bauen daraus eine API, die klar dokumentiert, versioniert und gegen Missbrauch abgesichert ist.

API-Review

OpenAPI-Spezifikation, Fehlerformate und Statuscodes auf Konsistenz prüfen.

Symfony-Umsetzung

DTOs, Serializer und Validator für saubere, typsichere Request/Response-Modelle einsetzen.

Security-Audit

Rate-Limiting, Auth-Schemes und Input-Validierung gegen echte Angriffsflächen absichern.

10. Zusammenfassung

AsyncAPI: Das Wichtigste auf einen Blick

Grundidee

AsyncAPI überträgt das OpenAPI-Prinzip auf asynchrone Kommunikation: Channels, Nachrichten und Payload-Schemas maschinenlesbar beschreiben.

Protokoll-Agnostik

Dieselbe Spezifikation deckt AMQP, Kafka, MQTT und WebSockets ab, protokollspezifische Details kommen als Bindings hinzu.

Versionierung

Event-Schemas brauchen CI-geprüfte Kompatibilitätsregeln, da Breaking Changes bei mehreren unabhängigen Consumern besonders tückisch sind.

Einstieg

Mit einem einzelnen, gut verstandenen Nachrichtentyp als Proof of Concept starten, nicht die ganze Event-Landschaft auf einmal dokumentieren.

11. FAQ: AsyncAPI: Das Wichtigste auf einen Blick

1Was ist der Unterschied zwischen AsyncAPI und OpenAPI?
OpenAPI beschreibt synchrone REST-Endpoints mit Request/Response. AsyncAPI beschreibt asynchrone Kommunikation über Message-Queues, Event-Streams oder WebSockets, mit Channels statt Pfaden als zentralem Konzept.
2Funktioniert AsyncAPI mit RabbitMQ?
Ja, RabbitMQ über AMQP ist eines der unterstützten Protokoll-Bindings. Die Grundstruktur der Spezifikation bleibt protokollunabhängig, das AMQP-Binding ergänzt nur protokollspezifische Details wie Exchange-Typen.
3Gibt es AsyncAPI-Codegenerierung für PHP?
Das Ökosystem für PHP ist deutlich dünner als bei OpenAPI. In der Praxis dient die Spezifikation häufiger als verbindliche Dokumentation für handgeschriebene DTOs statt als vollautomatische Codegen-Quelle.
4Wie zeige ich eine AsyncAPI-Spezifikation im Browser an?
Mit AsyncAPI Studio, dem Pendant zu Swagger UI, das eine interaktive, durchsuchbare Ansicht aller Channels und Nachrichten mit Beispiel-Payloads erzeugt.
5Kann ich AsyncAPI und OpenAPI im selben Projekt nutzen?
Ja, das ist sogar der Normalfall in hybriden Systemen mit sowohl REST-Endpoints als auch Event-Kommunikation. Beide Spezifikationen lassen sich parallel im selben Repository und Dokumentations-Portal pflegen.
6Wie verhindere ich, dass die AsyncAPI-Spec veraltet?
Am zuverlässigsten durch eine CI-Prüfung, die bei Änderungen am Message-Handler-Code auf eine fehlende Aktualisierung der Spezifikation hinweist. Ohne diese Kopplung veraltet sie wie jede unversionierte Dokumentation.
7Was passiert bei einer Breaking Change in einem Event-Schema?
Da mehrere unabhängige Consumer eine Nachricht verarbeiten können, ohne dass der Producer sie alle kennt, brechen entfernte oder umbenannte Felder Consumer oft stillschweigend. Eine neue Nachrichtenversion mit Übergangsphase ist der sichere Weg.
8Lohnt sich AsyncAPI für ein kleines Projekt mit wenigen Queues?
Bei sehr wenigen, stabilen Message-Typen ist der Mehrwert gegenüber einer kurzen Wiki-Notiz begrenzt. Der Nutzen steigt deutlich mit der Anzahl der Nachrichtentypen und der Anzahl der Teams, die sie konsumieren.
9Unterstützt AsyncAPI auch Kafka?
Ja, Kafka ist eines der am besten unterstützten Protokoll-Bindings, mit spezifischen Erweiterungen für Kafka-Konzepte wie Partitionierung und Consumer-Groups.
10Wie beginne ich am besten mit AsyncAPI in einem bestehenden Projekt?
Mit einem einzelnen, gut verstandenen Nachrichtentyp als Proof of Concept, um die Syntax kennenzulernen und den Dokumentationsaufwand realistisch einzuschätzen, bevor die gesamte Event-Landschaft beschrieben wird.