Frameworks in Go

von Tobias Kündig

    Das Wichtigste in Kürze

  • One size does not fit all
    Frameworks als Applikationsschablonen passen teilweise nur bedingt für den gegebenen Anwendungsfall.
  • Libraries statt Frameworks
    In der Go-Community wird vielerorts aktiv von der Verwendung von Frameworks abgeraten.
  • Go's Standardbibliothek hat es in sich
    Die Standardbibliothek macht das Erstellen von HTTP-Diensten in Go zum Kinderspiel.
  • Weniger Abhängigkeiten für einfachere Updates
    Je näher man sich an die Vorgaben der Standardbibliothek hält, desto einfacher werden zukünftige Updates.

Alles steht Kopf

Begibt man sich als PHP-Entwickler in die Welt von Go, denkt man alles steht Kopf: Galt es bisher als Neuerfindung des Rades oder als akuter Fall des Not-invented-here-Syndroms, wenn bei der Entwicklung einer PHP-Applikation auf ein Framework verzichtet wird, so wird in Go vielerorts aktiv davon abgeraten.

Die Gründe dazu und Empfehlungen für das Arbeiten im Go-Ökosystem werden im folgenden Beitrag erläutert.

One size fits all?

Im Jahr 2005 wurde CakePHP als eines der ersten PHP-Web-Frameworks veröffentlicht, welches auch heute noch aktiv entwickelt wird. Seither ist es üblich, dass beim Entwickeln von PHP-Applikationen zu Frameworks gegriffen wird.

Diese sind getestet, bieten die wichtigsten Basisfunktionalitäten und nehmen dem Entwickler viele Entscheidungen ab ‒ sie bieten somit ein gutes Fundament.

Doch nicht jede Applikation benötigt das gleiche Fundament: Das Problem bei Frameworks wie Laravel oder Symfony ist oft, dass sie mehr Funktionalität bereitstellen, als benötigt wird. Durch verschiedene Adapter für Datenbanken, Queues und Caches werden Infrastrukturentscheidungen ins Framework verschoben. Diese müssen dann bedingt durch den kurzlebigen Lebenszyklus von PHP-Prozessen bei jedem einzelnen Seitenaufruf wieder neu abgearbeitet werden (Verbinde ich zu MySQL oder Postgres? Speichere ich die Session in Redis oder im Dateisystem?) obwohl sich an diesen Gegebenheiten nur höchst selten etwas verändert.

Diesem Problem wird mit der Einführung der opcache.preload Direktive in PHP 7.4 sicher etwas entgegengewirkt, dennoch ist man mit mehr Abhängigkeiten unterwegs, als notwendig wären.

Selbst der Erfinder von PHP, Rasmur Lerdorf, hat sich im Jahr 2013 während seines Vortrages am PHP Framework Day negativ zur aktuellen Framework-Situation geäussert.

Warum wir Frameworks dennoch verwenden

Auch wenn die Verwendung von Frameworks einige Nachteile mit sich bringt, ist sie für PHP-Entwickler meist die bessere Alternative. Es benötigt schlichtweg zu viele manuelle Arbeitsschritte, um die Basisfunktionalität für eine komplexere Anwendung in reinem PHP zusammenzustellen.

Hinzu kommt, dass heute viele PHP-Bilbliotheken spezifisch für Frameworks entwickelt werden und framework-unabhängige Bibliotheken immer seltener zu finden sind. Dieses Problem wollte man mit PSRs angehen. Leider haben diese bisher mehr für Drama als für Lösungen gesorgt.

Warum Frameworks für Go nicht zwingend notwendig sind

Anders ist dies bei Go: Go wurde von Anfang an für die Anwendung im modernen Web entwickelt. Es bringt viele Funktionalitäten in der Standardbibliothek mit, welche in anderen Programmiersprachen nur mit Frameworks einfach zu erhalten sind. So ist zum Beispiel das Erstellen einer Controller-Methode in Go ohne Framework ein Kinderspiel:

http.Handle("/hello", Handler)

func Handler(w http.ResponseWriter, r *http.Request) {
     fmt.Fprint(w, "Hello world!")  
}

Dank des testing Pakets der Standardbibliothek kann dieser Handler dann auch ohne separates Testing-Framework getestet werden:

func TestHelloWorld(t *testing.T) {
    request, _ := http.NewRequest("GET", "/hello", nil)
    response := httptest.NewRecorder()

    // Der Handler wird mit dem Test-Request aufgerufen, die Response
    // kann dann mit einfachen If-Statements getestet werden.
    Handler(response, request)

    if response.Code != 200 {
        t.Fatalf("Handler() returned wrong status code: got %v want 200", response.Code)
    }

    expected := []byte(`Hello world!`)
    if ! bytes.Equals(response.Body.Bytes(), expected) {
        t.Fatalf("Handler() returned wrong body: got %v want %v", response.Body.Bytes(), expected)
    }
}

Was in PHP durch PSRs definiert werden muss, ist in Go bereits vorhanden. Wer eine Routing-Bibliothek entwickeln will, hält sich an die im Paket net/http definierten Interfaces (PSR-15). Wer eine Logging-Bibliothek entwickelt, sollte sich das log Paket ansehen (PSR-3). So entwickelte Bibliotheken sind automatisch framework-unabhängig und vielseitig einsetzbar.

Ganz ohne Abhängigkeiten geht es nicht

Schnell wird klar, dass Go von Haus aus bereits sehr viele Komponenten eines typischen Web-Frameworks mitbringt und viele Standards definiert sind. Dennoch ist es aus Gründen der Zeit und Sicherheit unsinnig, alle Funktionalitäten selber zu implementieren.

Auch wird jedem Go-Entwickler schnell klar, dass die Standardbibliothek eine gute Basis bietet, jedoch nicht jeden Anwendungsfall benutzerfreundlich abdeckt (wie z. B. HTTP-Verben oder dynamische Routes in net/http).

Aber anstatt gleich zum Framework zu greifen, ist es in Go üblich, sich die benötigten Komponenten aus dem überaus grossen und stabilen Ökosystem von Bibliotheken zusammenzusuchen. Der Grossteil davon ist darauf ausgelegt, framework-unabhängig zu agieren.

Diese Vorgehensweise resultiert in Applikationen mit weniger unbenötigten Funktionen, weniger Abhängigkeiten und einfacherer Struktur.

Wie immer sollte man natürlich das richtige Tool für den richtigen Job verwenden. Obwohl oft von Frameworks abgeraten wird, gibt es Projekte wie Buffalo oder Revel. Solche Projekte bieten eine praktikable Lösung für schnelle Entwicklungen, wie man es sich von Laravel & Co. gewohnt ist.

In den nächsten Blogeinträgen in dieser Serie wird auf einige Möglichkeiten eingegangen, wie gängige Komponenten aus PHP und dessen Frameworks sehr einfach mit Go nachgebaut werden können.

Ein Beitrag aus dieser Serie
Go

Tutorials, Informationen und Gedanken zur Go-Programmiersprache.

Weitere Beiträge anzeigen »
Mehr aus dieser Kategorie
Entwicklung
Hier findest du Blogartikel technischer Natur.
Weitere Beiträge anzeigen »

Los geht's!

Kontaktiere uns noch heute

Für Offerten, technische Anfragen oder einfach nur um Hallo zu sagen.