Phoenix ist ein beliebtes Webframework, das auf der Programmiersprache Elixir basiert. Für Entwickler, die gerade erst mit Phoenix arbeiten, stellen sich häufig viele Fragen rund um das Thema Contexts. Was sind Contexts eigentlich? Warum braucht man sie? Und wie benennt man sie sinnvoll? Oftmals wirkt das Konzept von Contexts komplizierter als es tatsächlich ist. Dabei sind Contexts in Wahrheit simple Bausteine, die helfen, Anwendungen übersichtlich, modular und wartbar zu gestalten. Im Kern sind Contexts nichts anderes als gewöhnliche Elixir-Module, die zusammengehörige Funktionen gruppieren.
Sie helfen dabei, den Business Logic Layer einer Anwendung eindeutig zu strukturieren und klar von der Web- oder Oberflächebene zu trennen. Wenn man das Prinzip erst einmal verstanden hat, verliert das Thema schnell seinen Schrecken und wird zum nützlichen Werkzeug für jede Phoenix-Anwendung. Der Konflikt, der viele Einsteiger beschäftigt, entsteht oft durch die Vermischung von Kernlogik und Web-spezifischen Elementen. In einer typischen Phoenix-Anwendung befindet sich der größte Teil des Codes im Verzeichnis lib. Innerhalb davon wird der Code meist in zwei große Teile gegliedert: lib/<app_name> für die allgemeine Geschäftslogik und lib/<app_name>_web für die rein webbezogenen Dinge.
Um das an einem Beispiel zu erläutern, nehmen wir ein fiktives Chatprogramm namens Slax, das mit Phoenix entwickelt wurde. Innerhalb von Slax befindet sich der Kern der Anwendung in lib/slax, wo sich beispielsweise Funktionen zur Verwaltung von Chaträumen, Nachrichten und Nutzerrechten finden. Die Logik dort kümmert sich etwa darum, die Rechte eines Nutzers zu überprüfen, eingehende Nachrichten zu validieren, Nachrichten in der Datenbank zu speichern sowie Benachrichtigungen zu versenden. Diese Abläufe sind unabhängig davon, ob Slax per Web, Mobile-App oder Kommandozeile benutzt wird. Die sogenannten Contexts organisieren genau diese Kernfunktionalitäten.
Sie sind die Ebene, auf der die Geschäftsregeln kodiert werden, und dienen als Schnittstelle nach außen. Im Gegensatz dazu befindet sich alles, was mit Web-spezifischen Herausforderungen zu tun hat – wie das Routing von HTTP-Anfragen, das Authentifizieren von Nutzern oder das Rendern von HTML – in lib/slax_web. Hier nehmen Controller, Views, LiveViews und der Router zentrale Rollen ein. Wichtig ist, dass die Web-Schicht niemals direkt mit der Datenbank oder niedrigeren Modulen kommuniziert, sondern immer über die Contexts. Warum ist das relevant? Weil dadurch klare Abgrenzungen entstehen und die Wartbarkeit stark verbessert wird.
Ein Beispiel verdeutlicht das gut: Um alle Chaträume im Webinterface anzuzeigen, könnte man theoretisch die Datenbank direkt im Controller abfragen. Praktisch ist das jedoch problematisch, denn es führt zu einer engen Kopplung des Controllers an die Datenbank und macht das System anfällig für Fehler und unerwünschte Seiteneffekte. Stattdessen bringt ein Context-Modul namens Chat die Geschäftslogik an eine zentrale Stelle. Dort wird eine Funktion wie list_rooms implementiert, die genau diese Aufgabe übernimmt. Der Controller im Web-Bereich ruft dann nur diese Funktion auf.
Für den Controller ist es dabei unerheblich, wie genau list_rooms umgesetzt ist. Die Daten könnten aus einer Datenbank, einem externen Dienst oder sogar einer Testquelle stammen. Diese lose Kopplung ist ein entscheidender Vorteil von Contexts. Sie erlauben es, die innere Funktionsweise einer Applikation zu verändern, ohne die Schnittstellen zu beeinflussen. Darüber hinaus sorgt dieses Muster für bessere Testbarkeit, da die Core-Logik isoliert vom Web-Framework geprüft werden kann.
Ein weiterer Punkt, der häufig Unsicherheit bei Neulingen hervorruft, ist die Wahl der Context-Namen. Hier gilt jedoch: einfache und intuitive Benennungen reichen völlig aus. Oftmals orientiert man sich an den logischen Domänen innerhalb der Anwendung, wie etwa Chat, User Management oder Billing. Es gibt keine Notwendigkeit, Contexts exakt nach Ecto-Schemas oder Controller-Namen zu benennen. Vielmehr geht es darum, zusammengehörige Funktionen thematisch zu bündeln.
Phoenix gibt hier zwar Empfehlungen, zwingt aber keine strikten Regeln auf. Die Flexibilität, die Contexts bieten, sorgt manchmal auch für Verwirrung, besonders im Vergleich zu Frameworks, die strengere Konventionen vorgeben. Aber genau diesen Gestaltungsspielraum sollte man als Stärke sehen: Mit zunehmender Größe der Anwendung kann man die Contexts aufspalten, umbauen oder zusammenführen, je nach Bedarf. So wachsen die Contexts mit den Anforderungen mit und bieten eine saubere Architektur. Zusammengefasst sind Phoenix Contexts eine einfache, aber zentrale Technik, die hilft, den Code klar zu organisieren, Verantwortlichkeiten sauber zu trennen und die Geschäftslogik unabhängig von der Darstellung zu halten.
Sie bilden die Brücke zwischen der Web-Schicht und den darunterliegenden Diensten wie der Datenbank. Wer sich das in seiner Anfangsschwierigkeit bewusst macht und den Gedanken akzeptiert, dass es sich schlicht um übersichtlich gruppierte Module handelt, wird die Vorteile schnell zu schätzen wissen. Bei der Entwicklung mit Phoenix lohnt es sich, nichts zu überdenken oder durch zu viele Details abzulenken. Einfach anfangen, Kontextnamen sinnvoll wählen und die Funktionen so zusammenfassen, wie es die Anwendung logisch nahelegt. Mit dieser Herangehensweise lässt sich Phoenix besonders produktiv und nachhaltig nutzen, was gerade bei größeren Projekten essenziell ist.
So entfaltet Phoenix sein volles Potenzial als ein modernes Webframework für skalierbare, wartbare und flexible Anwendungen auf Basis von Elixir.