AsyncAPI
Binde eine AsyncAPI-Spezifikation ein und erhalte eine native Event-Referenz – eine echte Seite pro Send- und Receive-Operation, in deiner Sidebar und in der Suche.
Event-gesteuerte APIs verwenden den Adapter asyncapi() aus blume/reference. Er wird unter reference neben etwaigen OpenAPI- oder GraphQL-Adaptern aufgeführt. Er akzeptiert dieselben Optionen wie openapi() und rendert mit demselben nativen Renderer. Jede send/receive-Operation wird zu einer echten Seite. Sie enthält Schematabellen für Message-Payload und Header, Kanalparameter, Protokoll-Bindings und einen Authorization-Abschnitt, der aus den securitySchemes der Spezifikation abgeleitet wird (auf Server- und Operationsebene, Alternativen als „oder“-Gruppen). Dazu kommt ein Try it-Nachrichten-Composer. Da jede Operation eine echte Blume-Seite ist, bekommt sie ihre eigene URL, taucht in der Seitensuche und in llms.txt auf und erhält ein Open-Graph-Bild – genau wie jede handgeschriebene Doku-Seite.
import { defineConfig } from "blume";
import { asyncapi } from "blume/reference";
export default defineConfig({
reference: [asyncapi({ spec: "./asyncapi.yaml" })],
});
Damit wird die Referenz unter /events eingehängt (eine Übersichtsseite), und jede Operation bekommt darunter ihre eigene Seite. spec ist entweder eine http(s)-URL oder ein Pfad zu einer lokalen JSON- oder YAML-Datei in deinem Projekt. Wie jede Referenz fügt sie nicht von selbst einen Tab im Header hinzu. Richte einen Navigations-Tab auf ihre Route, um sie sichtbar zu machen und die Operations-Sidebar darauf zu beschränken:
navigation: {
tabs: [{ label: "Events", path: "/events" }],
}
Spezifikationsversionen
AsyncAPI-2.x-Spezifikationen werden automatisch auf 3.x normalisiert, und zwar mit dem offiziellen AsyncAPI-Converter. So werden publish/subscribe-Kanäle auf send/receive-Operationsseiten mit stabilen URLs abgebildet. Wenn du die Spezifikationsdatei später selbst mit dem Converter aktualisierst, verschiebt sich also nichts. Der Converter ist eine optionale Peer-Dependency. Wenn deine Site eine 1.x- oder 2.x-Spezifikation nutzt, installiere ihn also (npm install @asyncapi/converter). Ohne ihn bricht der Build ab und nennt dir genau diesen Installationsbefehl. Eine 3.x-Spezifikation braucht nichts weiter. Operationen werden nach Tag gruppiert, Operationen ohne Tag unter ihrer Kanaladresse.
Codebeispiele
Codebeispiele sind protokollbewusst und richten sich nach dem Binding der Operation (oder dem Protokoll ihrer Server): wscat und ein Browser-WebSocket-Snippet für WebSockets, kcat für Kafka, mosquitto_pub/mosquitto_sub für MQTT. codeSamples filtert diese Auswahl, genauso wie es bei openapi() die Sprachen auswählt. Gibt es für ein Protokoll kein unterstütztes Tool, wird nur das Beispiel für den Message-Payload gerendert statt eines erfundenen Clients.
Gemeinsame Optionen
Alles, was für OpenAPI dokumentiert ist, gilt auch hier, einschließlich playground. Dazu gehören route, sources mit label/route und expandSchemas. Auch die Flags für die Indexierung pro Quelle gelten, einschließlich seoDescriptionSuffix: Der generierte Satz nennt hier den Kanal und die Aktion statt eines Endpunkts. Außerdem wird die Suche nach Operationszusammenfassung und Tag indexiert.
Stattdessen Scalar einbetten
asyncapi() rendert immer Blumes eigene Seiten. Wenn du stattdessen die UI von Scalar einbetten willst, trag einen scalar()-Adapter ein, der auf das AsyncAPI-Dokument zeigt. Das Embed erkennt den Dokumenttyp und rendert Kanäle, Operationen, Nachrichten und einen Models-Abschnitt. Scalar hat keinen eigenen AsyncAPI-Playground, also verzichtest du mit diesem Wechsel auf den Composer. Außerdem greift von den Einstellungen pro Quelle nur noindex.
Try it für Events
Nativ gerenderte Operationsseiten bringen auch hier ein Try it-Panel mit. Es funktioniert genau wie das OpenAPI-Panel: Der Server rendert es eingeklappt, und sein JavaScript wird erst geladen, wenn jemand es zum ersten Mal öffnet.
Unabhängig vom Protokoll öffnet sich das Panel mit einem Payload-Editor. Er ist mit den examples der Nachricht vorausgefüllt. Deklariert die Nachricht keine, nimmt er einen Beispielwert, der aus dem Payload-Schema erzeugt wird. Während du tippst, wird der Payload gegen das Payload-Schema der Nachricht validiert. Darunter findest du ein Eingabefeld pro Kanalparameter und eine Serverauswahl, die aus den servers des Kanals gespeist wird. Für jede andere URL gibt es ein Freitextfeld. Die protokollbewussten Codebeispiele bleiben mit dem Formular synchron, genau wie curl, js und python bei einer HTTP-Operation. Das Template der Kanaladresse wird mit den Parameterwerten befüllt, die du eingibst. Ein kopiertes wscat-, WebSocket-, kcat- oder mosquitto_pub-Snippet entspricht also dem, was im Formular steht.
Eine Live-Verbindung gibt es nur für WebSockets. Bei einem ws- oder wss-Binding verbindet sich das Panel mit der aufgelösten Kanal-URL, zeigt den Verbindungsstatus an und protokolliert jeden Frame mit Zeitstempel. AsyncAPI 3 beschreibt Aktionen aus Sicht der API, und das Panel hält sich daran. Bei einer receive-Operation empfängt die API etwas von dir. Deshalb bekommt sie einen Send-Button, der den zusammengestellten Payload veröffentlicht. Eine send-Operation streamt nur Nachrichten an dich, also verbindet sich das Panel dort nur und protokolliert mit. Es gibt keine Reconnect-Logik: Sobald ein Socket geschlossen ist, bleibt er zu, bis du dich erneut verbindest. Kafka, MQTT, AMQP und alle anderen Protokolle bekommen den Composer und die kopierbaren CLI-Beispiele. Das Panel weist auf der Seite auch ausdrücklich darauf hin: Blume täuscht keine Broker-Verbindung aus einem Browser-Tab vor.
Die Option playground von asyncapi() funktioniert wie die von openapi(). Mit dem nativen Renderer ist sie standardmäßig aktiviert, und mit false schaltest du sie komplett ab:
reference: [asyncapi({ spec: "./asyncapi.yaml", playground: false })],
Der Event-Composer fragt keine Broker-Zugangsdaten ab. Der Abschnitt Authorization auf jeder Operationsseite dokumentiert, was der Broker erwartet. Eine WebSocket-Verbindung überträgt nur das, was bereits in der URL steht. Für Event-Operationen wird nichts gespeichert.