AsyncAPI: Asynchrone Kommunikation für IoT und Microservices meistern

Inspiriert von Swagger und OpenAPI ermöglicht die Spezifikationssprache AsyncAPI die Beschreibung asynchroner Schnittstellen.

Lesezeit: 13 Min.
In Pocket speichern
vorlesen Druckansicht Kommentare lesen 11 Beiträge

(Bild: TierneyMJ / Shutterstock.com)

Von
  • Thilo Frotscher
Inhaltsverzeichnis

Die Integration von Softwaresystemen ist eine Daueraufgabe für Entwicklerinnen und Entwickler. Im Verlaufe der Jahrzehnte kamen hierzu verschiedenste Ansätze und Technologien zum Einsatz, Trends entstanden und verblassten wieder. In der jüngsten Vergangenheit avancierten APIs (Application Programming Interfaces) zum Mittel der Wahl. Der Begriff bringt zum Ausdruck, dass ein Softwaresystem eine definierte Schnittstelle zur Verfügung stellt, die andere Systeme nutzen können, um Daten auszutauschen oder bestimmte Funktionen auszulösen. Traditionell nutzen APIs in der Regel HTTP zum Übertragen von Daten und Anweisungen, seit einiger Zeit auch vermehrt andere Protokolle.

Aufgrund der zunehmenden Vernetzung von Softwaresystemen haben die bereitgestellten APIs oftmals eine ganze Reihe von Clients. Dies gilt insbesondere für Public APIs, die nicht auf einen geschlossenen Kreis bekannter Kommunikationspartner beschränkt sind. So entstehen digitale Geschäftsmodelle, bei denen eine API ein wichtiges oder sogar das Kernprodukt eines Unternehmens darstellt. Beispiele sind Bezahldienste wie PayPal oder Kartenanwendungen wie Google Maps. Solche Geschäftsmodelle haben den Begriff API Economy geprägt. War es noch vor einigen Jahren für Unternehmen zwingend notwendig, über eine Webpräsenz zu verfügen, um am Markt relevant zu sein, ist inzwischen – zumindest in einigen Branchen – das Bereitstellen einer API ein Erfolgsfaktor.

Im Zuge der API Economy wächst die Zahl verfügbarer APIs rasant. Unternehmen, die auf den Zug aufspringen wollen, sollten jedoch nicht einfach drauf los programmieren. Stattdessen sollte im ersten Schritt ein API-Design erfolgen. Dabei wird die geplante Schnittstelle zunächst nur definiert. Hierzu ist eine Reihe von Fragen zu klären: Welche Daten sollen ausgetauscht werden und – mindestens ebenso wichtig – welche nicht? Wie sollen die auszutauschenden Daten strukturiert sein? Welche Bezeichnungen sollen die einzelnen Datenfelder erhalten? Beim API-Design sollten idealerweise sowohl API-Betreiber als auch künftige Nutzer und Nutzerinnen involviert sein, sofern diese bereits bekannt sind. Die Schnittstelle sollte in sich konsistent, einfach zu verstehen und leicht erweiterbar sein.

Ein fehlendes oder mangelhaftes API-Design kann mittelfristig zu unschönen Herausforderungen führen. Denn ist eine Schnittstelle einmal im Betrieb und mehrere Clients nutzen sie, müssen alle Änderungen mit größtmöglicher Rücksicht auf diese Clients erfolgen. Nicht rückwärtskompatible Änderungen, wie etwa Umbenennungen von Attributen oder Pfaden, führen zu Anpassungsaufwänden bei den Entwicklungsteams der API-Clients. Daher ist im Zweifelsfall die Konsultation eines erfahrenen API-Experten empfehlenswert, der beim API-Design unterstützen kann.

Während der Design-Phase, die mehrere Iterationen umfassen kann, müssen die einzelnen Entwürfe in einer geeigneten Form dokumentiert werden. So entsteht eine gemeinsame Diskussions- und Arbeitsgrundlage, die zirkuliert und sich schrittweise erweitern oder verbessern lässt. Dafür eignet sich eine standardisierte Spezifikationssprache am besten.

Für HTTP-basierte APIs mit synchroner Kommunikation hat sich OpenAPI für diese Zwecke durchgesetzt. Die Spezifikationssprache ist aus dem verbreiteten Swagger hervorgegangen, erleichtert die formale Spezifikation von APIs und wird unter dem Schirm der Linux Foundation gepflegt. Im Wesentlichen ermöglicht es OpenAPI unterschiedliche URL-Pfade als Endpunkte für HTTP-Requests zu definieren. Für jeden einzelnen dieser Endpunkte lässt sich dann weiter spezifizieren, welche Request-Typen er jeweils unterstützen soll (GET, PUT, POST, DELETE und so weiter), welche Daten und Parameter gegebenenfalls zu senden sind und welche Status-Codes oder Daten ein API-Client in den Antworten erwarten kann.

Zum Beschreiben der Datenstrukturen führt OpenAPI keinen neuen Standard ein, sondern verwendet JSON Schema.

Lange Zeit waren Swagger und später OpenAPI für das Gros der Softwareprojekte ausreichend, da die überwiegende Mehrheit der implementierten Schnittstellen auf synchrone Kommunikation mit HTTP baute. Unter dem Einfluss von REST (Representational State Transfer) etablierte sich ein Trend, der SOAP als de-facto-Standard zur Integration von Softwaresystemen ablöste. Rund um OpenAPI entstand ein ganzer Kosmos unterschiedlicher Werkzeuge, von Editoren über Code-Generatoren und Test-Frameworks bis hin zu Rendering Engines, die aus einem OpenAPI-Dokument interaktive API-Dokumentationen im HTML-Format erstellen.

Mit dem Aufkommen neuer Technologien und Trends, darunter etwa das Internet of Things (IoT) sowie Microservice-Architekturen, bei denen die Kommunikation in aller Regel asynchron verläuft, änderte sich die Situation jedoch. Bei den immer beliebter werdenden ereignisbasierten Architekturen erfolgt der Austausch von Nachrichten oder Events über Kommunikationssysteme wie Kafka. Auch diese Kommunikationsform basiert auf Schnittstellen, damit sich Produzent und Konsumenten eines Ereignisses darüber abstimmen können, welche Informationen in den jeweiligen Nachrichten enthalten sind und über welche Kommunikationskanäle diese ausgetauscht werden. Die Kommunikation erfolgt hierbei typischerweise asynchron, HTTP kommt daher nicht in Frage. Da auch OpenAPI keine passende Lösung zur Spezifikation solcher asynchronen Schnittstellen bot, galt es, eine neue Spezifikationssprache zu entwickeln. So entstand die ebenfalls bei der Linux Foundation beheimatete AsyncAPI.

Hauptziel bei der Entwicklung von AsyncAPI war, die Spezifikation asynchroner APIs genau so einfach zu gestalten, wie das bei synchronen APIS mit OpenAPI gelang. Zudem sollte den zahlreichen Entwicklerinnen und Entwicklern mit Vorkenntnissen in OpenAPI der Einstieg möglichst einfach gelingen. Daher fiel der Entschluss, dessen bekannte Strukturen und Kernkonzepte weitestgehend in AsyncAPI einfließen zu lassen. Die Angleichung beider Spezifikationssprachen ist weitgehend gelungen, wie Abbildung 1 illustriert. Wer sich mit OpenAPI bereits auskennt, findet sich auch in AsyncAPI schnell zurecht.

Kompatibilität haben die AsyncAPI-Entwickler auch bezüglich der Spezifikation ausgetauschter Datenstrukturen erreicht. So lässt AsyncAPI – neben anderen Beschreibungssprachen – auch die Verwendung von JSON Schema zu. Im Falle von Architekturen mit gemischten Kommunikationsformen sind Entwicklerinnen und Entwickler daher in der Lage, die synchronen APIs mit OpenAPI und die asynchronen mit AsyncAPI zu spezifizieren, während sie für gemeinsam verwendete Datenstrukturen nur ein einziges JSON-Schema erstellen müssen, das beide API-Spezifikationen nutzen können.

Darüber hinaus ist AsyncAPI protokollunabhängig ausgelegt. Asynchrone Schnittstellen lassen sich also unabhängig vom konkreten Kommunikationsprotokoll zur Übertragung der Nachrichten oder Events beschreiben. Zur Auswahl stehen unter anderem AMQP, JMS, Kafka, MQTT, Solace, STOMP und WebSocket.

Strukturen von OpenAPI und AsyncAPI im Vergleich (Abb. 1).

(Bild: asyncapi.com )