joetjen.net
EN DE
Web-Framework

WebGlue

Ein Klebstoff-Framework, kein Monolith — Rings Einfachheit, Phoenix’ Anspruch. WebGlue ist ein in Praxis geschriebenes Web-Framework aus kleinen, austauschbaren Bibliotheken mit einem gemeinsamen Vertrag: Ein Request ist eine Map, eine Response ist eine Map, und ein Handler ist eine Funktion von einem zum anderen.

In Entwicklung · v0.8

Die Idee

Clojures Ring ist eher eine Spezifikation als eine Bibliothek: Ein Handler ist eine gewöhnliche Funktion, und Middleware ist eine Funktion, die einen Handler umhüllt. WebGlue nimmt dieses Muster und zieht es durch ein ganzes Framework — Routing, HTTP-Server, Templates, Sessions, Formulare, WebSockets, Pub/Sub, Presence und Server-Push — mit der Vollständigkeit von Phoenix oder Laravel als Ziel.

handler    :: Request -> Response
middleware :: Handler -> Handler

Eine WebGlue-Anwendung ist eine Auswahl zusammengeklebter Bibliotheken. Das Framework ist die Konvention, nicht der Code.

Grundsätze

  • Kleiner Kern, austauschbare Ränder.
  • Standards zuerst: HTTP/1.1, HTTP/2, RFC-6455-WebSockets, IPv4 und IPv6.
  • Entwurf vor Code: Jede Bibliothek beginnt als Spezifikation.
  • Keine versteckte Magie im heißen Pfad. Komposition sind lesbare Funktionsaufrufe — keine Makros, kein use.
  • Das Frontend ist kein eigenes Ökosystem: Es wird ebenfalls Praxis sein, für den Browser kompiliert.
  • Vollständig beim Release, monolithisch nie.
  • An den etablierten Standard andocken statt ihn neu zu erfinden — Bandit, Ecto, Absinthe, Oban, Swoosh, Redix.

Drei weitere Entscheidungen stehen fest: Markup ist Daten — ein Baum aus gewöhnlichen Praxis-Vektoren und -Maps, niemals Zeichenketten, und auch ein Template wird zu so einem Baum kompiliert; das Wire-Format ist DXN, mit JSON als Rückfall; Konfiguration ist CASC.

Ein erster Blick

Die Demo-Anwendung ist eine einzige Funktion. Von unten gelesen: Die Reihenfolge des Umhüllens ist die Reihenfolge der Verschachtelung, und nur hier wird sie festgelegt.

webglue_demo/apps/web/src/webglue/demo/web.prax
(defn app
  "The application: one function, request to response."
  [] :spec [-> function]
  (-> (router/handler (routes))
      (db/wrap {:repo webglue.demo.store.memory})
      (wrap-user)
      (static/wrap {:root (assets) :at "/assets"})
      (session/wrap {:store (memory/store)})))

Gebaut mit Lictor

Seit Oktober 2026 wird WebGlue nicht mehr für sich allein geplant. Lictor — Moderation für Live-Streamer, in Praxis geschrieben und im selben Repository — ist eine WebGlue-Anwendung und wird Journey für Journey gebaut: erst die ausgelieferte Website, dann die Registrierung, dann der Login. Braucht eine Journey etwas, das WebGlue nicht hat, wird es in WebGlue gebaut, auf einem eigenen Branch, während dieser Journey. Was eine Journey auslässt, kommt in WebGlues Backlog.

Lictors Registrierung brachte Formular-Bodies, CSRF-Schutz und einen Tailwind-Build in WebGlue 0.8. Seine Anwendungsfunktion hat dieselbe Form wie die der Demo:

lictor/apps/lictor_elysium/src/lictor/elysium.prax
(let [routed (-> (router/handler (routes))
                 (csrf/wrap)
                 (params/wrap)
                 (session/wrap {:store (sessions/store)})
                 (in-world world))]
  (static/wrap routed {:root (static-root) :at "/assets"}))

Die begleitende Demo-Anwendung, ein Ticketsystem, wächst weiter daneben und prüft, dass jede Bibliothek für eine gewöhnliche Anwendung taugt und nicht nur für Lictor.

Sprache und Laufzeit

WebGlue ist in Praxis geschrieben und läuft heute auf der BEAM: Namespaces werden zu .beam-Modulen, langlebiger Zustand lebt in OTP-Prozessen, und Pub/Sub läuft auf Erlangs pg. Etablierte BEAM-Bibliotheken — Bandit, Plug, WebSock, Redix — kommen über Praxis’ Interop zum Einsatz. Eine bewusste Ausnahme baut mit etwas anderem als der BEAM: Tailwinds eigenständiges CLI, angepinnt und per Prüfsumme kontrolliert geladen wie eine Abhängigkeit.

Die Frontend-Hälfte ist für Praxis’ Browser-Ziel geplant, und ihr Entwurf steht seit Oktober 2026: ein eigener reaktiver Kern in Praxis, der Solids Modell übernimmt — Komponenten laufen einmal, und nur was einen geänderten Wert gelesen hat, wird aktualisiert —, aber nicht Solids Laufzeit, und kein React-Ziel.

Wo es steht

Version 0.8.0 (19. Oktober 2026) umfasst einundzwanzig Bibliotheken und die Demo, alle implementiert und getestet — 872 Tests, darunter jedes dokumentierte Beispiel — für den Vertrag, Routing, zwei HTTP-Server, Templates, Content-Negotiation, Formular-Bodies, CSRF, Sessions, statische Dateien, einen Tailwind-Build, WebSockets, Pub/Sub, Presence, Clustering, Redis, Server-Push, Validierung und eine Nahtstelle zur Datenschicht. Alles ist als experimentell markiert. Der Fokus liegt auf dem Backend; das Frontend folgt.