WebAssembly, oder kurz Wasm, hat sich dank seiner schnellen, nahezu nativen Ausführungsgeschwindigkeit, der großen Auswahl an Programmiersprachen und dem robusten Deny-by-Default-Sandboxing-Modell immer wieder als revolutionäre Technologie erwiesen. Es wird im gesamten Web bereits in großem Umfang eingesetzt und ist auch auf der Serverseite ein beeindruckender Player.
Jedes aufstrebende Ökosystem braucht eine Vision davon, wie alle Teile zusammenpassen, und genau hier kommt das WebAssembly-Komponentenmodell ins Spiel. Das Komponentenmodell ist ein System, das Interaktionen zwischen einzelnen Einheiten von WebAssembly-Code und Interaktionen zwischen WebAssembly-Code und einer Hostumgebung erleichtert. Alles dreht sich um das Konzept der WebAssembly-Komponenten, die im Wesentlichen reguläre Wasm-Module mit codierten Datentypen sind. Diese Typen ermöglichen die Generierung von Verbindungscode im Hintergrund, der dafür sorgt, dass die Komponenten nahtlos miteinander kommunizieren.
Das Komponentenmodell läutet ein neues Zeitalter moderner Softwareentwicklung ein – Entwickler können Komponenten aus jedem beliebigen Programmiersprachen-Ökosystem auswählen und zu einer einzigen App zusammenstellen. Sie haben eine Datenverarbeitungs-App in Python, benötigen aber einen effizienten Parser aus Rust? Kein Problem. Ein Team in Ihrer Organisation beherrscht Go, ein anderes schreibt aber nur JavaScript? Überhaupt kein Problem – jedes Team kann WebAssembly-Komponenten erstellen, die sich problemlos zusammensetzen lassen.
WebAssembly steht vor einem Problem, das wir bei nahezu jeder neuen Codeausführungsplattform feststellen: Wie können wir Daten sicher, geschützt und effizient zwischen separaten Codeeinheiten austauschen, die möglicherweise von völlig unterschiedlichen Toolchains für Programmiersprachen erstellt wurden? Im Allgemeinen könnten zwei separate WebAssembly-Module das tun, was viele Systeme tun, und Daten zwischen ihnen in JSON, Protobuf oder einem anderen gängigen Datenaustauschformat austauschen. Das Serialisieren und Deserialisieren dieser Formate ist ziemlich aufwändig, und angesichts der Tatsache, dass die beiden Module, die miteinander kommunizieren möchten, wahrscheinlich nebeneinander von derselben Laufzeitumgebung und nicht über ein Netzwerk ausgeführt werden, ist eine bessere Implementierung möglich.
Das Problem liegt in der Art und Weise, wie jede Programmiersprache Daten darstellt. Sprachimplementierungen können unterschiedliche Kodierungen für Zeichenfolgen verwenden. Eine Sprache speichert möglicherweise lieber sequenzielle Daten als Array, während eine andere verknüpfte Listen bevorzugt. Damit Code aus verschiedenen Sprachen miteinander kommunizieren kann, müssen sie sich auf eine gemeinsame Form für alle Datentypen einigen. Dies wird als Application Binary Interface oder ABI bezeichnet. In der Praxis ist keines davon gleich. Wenn Code, der in einer Sprache geschrieben ist, mit Code, der in einer anderen Sprache geschrieben ist, kommunizieren soll, muss sich normalerweise ein armer Entwickler hinsetzen und sorgfältig (und mühsam) Code schreiben, um ihn zwischen den beiden Sprachen zu übersetzen. Es erfordert genaue Kenntnisse über die Funktionsweise beider Sprachen und ist äußerst fehleranfällig. Einige Sprachökosysteme haben es geschafft, Tools zu entwickeln, die dies automatisch erledigen können, aber selbst dann ist dies nur für ausgewählte Sprachen möglich.
Glücklicherweise definiert das Komponentenmodell ein gemeinsames Datenformat für alle Sprachen, das sogenannte kanonische ABI. Um es dem Menschen einfacher zu machen, gibt es auch eine Schnittstellendefinitionssprache namens WebAssembly Interface Types oder WIT zur Beschreibung von Komponentenschnittstellen.
Wir haben also alle diese Komponenten, aber wie können wir feststellen, wo wir sie verwenden können? Schließlich läuft WebAssembly an vielen Orten – in Webbrowsern, auf Servern, am Rand, auf kleinen Geräten und mehr – und überall mit unterschiedlichen Fähigkeiten. WIT bringt uns das Konzept von Welten . Eine Welt ist die Schnittstelle, der eine Komponente entspricht. Es handelt sich um eine Reihe von Funktionen, die eine Komponente importieren kann, und eine Reihe von Funktionen, die die Komponente exportiert. Dadurch können wir relativ einfach über Komponenten und ihre Zusammensetzung nachdenken. Hier ist die Definition einer Komponente, die in der Welt „wasi:cli/command“ lebt und Komponenten beschreibt, die auf einer Terminal-Befehlszeile ausgeführt werden:
Quelle: https://github.com/WebAssembly/wasi-cli , der Kürze halber geändert
Diese Komponente kümmert sich um Dinge wie das Dateisystem und die Zufälligkeit und verfügt gleichzeitig über Streams für Eingabe und Ausgabe. Wichtig ist jedoch, dass sie eine Funktion bereitstellt, die ausgeführt wird, wenn der Befehl aufgerufen wird.
Welten können von jedem definiert werden, es gibt jedoch eine Reihe von standardisierten Welten für Komponenten, die HTTP-Anfragen verarbeiten, auf USB-Geräte zugreifen, KI-Modelle verwenden und vieles mehr können. Hostumgebungen können bekannt geben, welche Welten sie implementieren, damit Entwickler leicht erkennen können, welche Komponenten funktionieren. Da Komponenten zusammensetzbar sind, ist es auch möglich, einige Welten in Bezug auf andere Welten zu implementieren und die beiden Komponenten zusammenzusetzen. Wenn Sie beispielsweise eine Hostumgebung haben, die eine Sockets-Welt implementiert, aber eine Komponente, die HTTP-Anfragen in einer HTTP-Welt stellen möchte, können Sie eine Adapterkomponente schreiben, die die HTTP-Welt mithilfe von Sockets implementiert:
Mit einer einfachen Zusammensetzung kann Ihre Komponente jetzt ohne Änderungen in der Sockets-Welt ausgeführt werden! Die Möglichkeiten sind endlos.
Das Komponentenmodell ist von großer Bedeutung, nicht nur für WebAssembly, sondern für alle Entwickler überall. Dies wird die Art und Weise, wie Entwickler über Software nachdenken und sie entwickeln, grundlegend ändern. Es gibt bereits jede Menge nützliche Funktionen, und wir stehen noch ganz am Anfang. Bleiben Sie über die Entwicklungen im WebAssembly-Ökosystem auf dem Laufenden, denn mit der zunehmenden Akzeptanz werden wir mit Sicherheit immer mehr überzeugende Anwendungsfälle sehen.