Skalierbare, robuste Webanwendungen mit Elixir und Phoenix

Seite 4: Der Webserver Phoenix

Inhaltsverzeichnis

Als Standard-Webserver für Elixir hat sich Phoenix etabliert. Phoenix kombiniert diverse Bibliotheken mit Makros und Konventionen zu einem umfangreichen Paket, mit dem sich schnell erste Ergebnisse erzielen lassen, das aber trotzdem keine Kompromisse bei der Geschwindigkeit eingeht.

Die Gesamtarchitektur von Phoenix umfasst verschiedene Bausteine. Eine Beschreibung der für das Beispielprogramm relevanten folgt später. Channels als Abstraktion über Websockets sind ebenso wenig nötig wie die für die Code-Organisation der Business-Logik bei komplexeren Programmen üblichen Contexts. Beide Elemente bleiben daher in den weiteren Betrachtungen unberücksichtigt.

Die Basisarchitektur des Webservers Phoenix (Abb. 2)

Der Game-Server des Beispielprogramms nutzt nur wenige Aspekte der Phoenix-Funktionen, da die eigentliche Bedienoberfläche nicht via Phoenix-Templates umgesetzt, sondern als Elm Single Page Application ausgelegt ist. Der Phoenix-Webserver startet im Projektverzeichnis via mix phx.server. Anschließend steht unter der Adresse http://localhost:4000 die Standardstartseite bereit:

Allgemeine Startseite eines neuen Phoenix-Projekts (Abb. 3)

Anschließend sind im Router, durch den alle Anfragen immer laufen müssen, in /lib/game_web/router.ex die Routen anzulegen, um den Zugriff via HTTP zu ermöglichen. Es bietet sich an, vorher eine API-Pipeline zu definieren, in der die bei jedem API-Zugriff zu durchlaufenden Schritte als Kette von Plugs – also kleine, den Request oder Response verändernde Funktionen – festgehalten sind:

pipeline :api do
plug :accepts, ["json"]
plug :fetch_query_params
end

Die benötigten Routen zum Starten und Beenden von Game-Sessions sowie zum Übermitteln einer geratenen Zahl werden der Einfachheit halber allesamt als GET-Requests implementiert:

scope "/api", GameWeb do
pipe_through :api

get "/guess", GuessController, :guess
get "/session/connect", SessionController, :connect
get "/session/disconnect", SessionController, :disconnect
end

Durch die Angabe eines Scopes lassen sich automatisch alle Routen mit diesem Präfix versehen und pipe_through sorgt dafür, dass jede Anfrage die entsprechende Plugs-Pipeline durchläuft. get wiederum erwartet als Argumente eine URL, einen Controller, an den die Anfrage durchgereicht wird, und die anzusteuernde Funktion im Controller als Atom. Controller dienen in Phoenix als Brücke zwischen HTTP-Anfragen und -Antworten sowie der Geschäftslogik im jeweiligen Context.

Nach dem Speichern der Datei lässt sich die korrekte Erstellung der Routen in der Kommandozeile via mix phx.routes prüfen. Dies ist vor allem dann sehr hilfreich, wenn komplexe Scope-Hierarchien erstellt oder aber mit dem resource-Makro ganze REST-Ressourcen mit nur einer Zeile Code festgelegt werden. mix phx.routes zeigt immer die einzelnen, tatsächlich generierten Routen an.