Get in touch
In dieser dreiteiligen Blogartikel-Serie wollen wir Dir Flamingo, das auf Go-basierende, modulare Open-Source-Framework von AOE, schrittweise näherbringen. Freu Dich auf spannende Deep Dives in die Programmiersprache Go, interessante Fakten über Vor- und Nachteile von Development Frameworks im Allgemeinen und im dritten Teil zahlreiche Infos, wie Du mit Flamingo neue Maßstäbe bei der Erstellung von maßgeschneiderten, schnellen und flexiblen Webanwendungen setzen kannst.
Starte jetzt gleich mit Teil 1: Die Wahl der Programmiersprache: JUST GO FOR IT!
Jede neue Programmiersprache ist erst einmal für ihre Entwickler:innen ein unbeschriebenes Blatt, mit dem Vorteil, dass sie ihre persönlichen Erfahrungen aus bereits existierenden Sprachen in eine weiterentwickelte Lösung einfließen lassen können. Developer konzentrieren sich so ausschließlich auf die Entwicklung einer Programmiersprache, die auf zeitgenössische, moderne Infrastrukturen sowie aktuelle technische Herausforderungen und Anforderungen ausgerichtet ist.
Go wurde bei Google von einem sehr erfahrenen Team von Programmierern entwickelt, darunter Robert Griesemer, Ken Thompson (Designer und Schöpfer von UNIX und C) und Rob Pike (Miterfinder von UTF 8 und UNIX) und erstmals 2009 als Open-Source-Projekt veröffentlicht. Sie gilt als junge Programmiersprache, die für das Zeitalter von Cloud Computing, Containerisierung, serviceorientierten Architekturen und DevOps entwickelt wurde. Gleichzeitig haben sich ihre Schöpfer auf Skalierbarkeit und Benutzerfreundlichkeit fokussiert. Und das ist ihnen auch gelungen. Go hat Lehren aus der Vergangenheit gezogen und basiert auf dem Mantra „ein Problem – eine Lösung”. Das bedeutet in der Praxis, dass es für jedes Problem nur wenige Lösungen gibt. Aber kein Grund zur Sorge: Dadurch wird das Erlernen der Sprache vereinfacht und die Programmierung in großen, teamübergreifenden Programmierumgebungen vereinheitlicht. Das Endergebnis ist eine attraktive neue Kombination aus leistungsstarken, zeitgemäßen technischen Funktionen, untermauert durch eine Philosophie der Einfachheit.
Die Kehrseite der Medaille ist, dass der Erfolg jeder Programmiersprache unmittelbar von der Akzeptanz der Entwickler:innen, der User-Community und dem florierenden Ökosystem (Tools, Bibliotheken usw.) abhängt. Bei jeder neuen Sprache muss all dies von Grund auf neu aufgebaut werden. Unabhängig von den technischen Vorzügen befindet sich eine frühe Einführung so in der Regel in einem Teufelskreis: Entwickler:innen können die Kosten für die Einarbeitung in neue Fähigkeiten nicht rechtfertigen, wenn keine Nachfrage auf dem Markt besteht. Und die Einführung in Unternehmen ist zu riskant, da es an entsprechend ausgebildeten Entwickler:innen fehlt. In weniger als 15 Jahren hat sich Go überzeugend hiervon gelöst und einen eigenen, leistungsorientierten Kreis von Hyperscalern, Start-ups und inzwischen auch Unternehmensanwendern geschaffen.
Google und andere Unternehmen wie Uber, SoundCloud und Dropbox haben es hervorragend verstanden, Spitzentalente aus den eigenen Reihen zu rekrutieren. Dadurch konnte ein großer Pool an Go-erfahrenen Expert:innen aufgebaut werden, die mit den Feinheiten der Entwicklung großer Webanwendungen vertraut sind. Die innovationshungrigsten Entwickler:innen sahen in Go den Weg auf eine aufregende, hochmoderne Spielwiese. Natürliche Karrierewege innerhalb dieses frühen Talentpools führten dazu, dass Go weiter in die Welt der Start-ups vordrang.
Go hat einen fulminanten Start hingelegt und ist so für die meisten Pionierunternehmen wieder attraktiv geworden. Die Sprache hat einfach viele Stärken und einen Pool von Entwickler:innen im Hintergrund, die hochqualifiziert in der Skalierung von Webanwendungen sind. Und für die Unternehmen, die den Erfolg der Hyperscaler nachahmen wollen, ist das natürlich ideal. Ihre besten Entwickler:innen wollten neue Projekte in Go starten. Und das Starten neuer Go-basierter Projekte bot ihnen Möglichkeiten, weitere erfahrene Top-Talente zu gewinnen. Die frühe Einführung von Go in Unternehmen war sicherlich ein mutiger Schritt. Er war zweifellos riskanter als die Fortsetzung von Projekten mit traditionelleren Sprachen. Es besteht immer das Risiko, dass eine Hype-Blase um die neuesten Entwicklertechnologien entsteht. Außerdem war es schwieriger, Talente aus einem begrenzten und sehr gefragten Pool von Entwickler:innen zu rekrutieren und zu halten. Für die meisten hat sich das Risiko jedoch gelohnt.
Infolgedessen hat Go in Softwareentwicklerkreisen rasch eine bedeutende Nische eingenommen und ist zu einer etablierten Unternehmenstechnologie geworden. Das Risiko hat sich quasi in Luft aufgelöst, während die Vorteile weitergewachsen sind. Go wird jetzt in Umfragen durchgängig als eine der am schnellsten wachsenden und am meisten gefragten Programmiersprachen eingestuft. Trotz unterschiedlicher Meinungen in Umfragen zu der Beliebtheit von Sprachen, unterschätzen selbst die optimistischsten Schätzungen, die Go weit unter den Top Ten der Programmiersprachen einstufen, die wahre Popularität von Go in der Nische von High-End-Webanwendungen im großen Stil.
Die technischen Vorzüge des Code Formats „uld” und die Betonung der Einfachheit und Lesbarkeit von Go machen die Programmiersprache für viele Entwickler:innen sehr attraktiv. Das Beste daran ist, dass man sich die Sprache auch als Anfänger oder Quereinsteiger ziemlich schnell aneignen kann. Go hat eine übersichtliche Syntax, die leicht zu erlernen ist und dafür sorgt, dass der Code gut lesbar und wartbar bleibt. Die Einfachheit ist ein echtes Highlight im Vergleich zu vielen anderen Programmiersprachen, auch solchen, die auf den ersten Blick ähnlich leistungsfähig scheinen wie Go.
Sprachen wie C, Rust oder Java haben die Knappheit des Codes zugunsten der kreativen Ausdrucksfähigkeit der Entwickler:innen eingetauscht. Man könnte sagen, sie sind das CISC zu Go's RISC. Außerdem bietet Go eine Menge syntaktischer Goodies und eine umfassende Standardbibliothek, eine der vollständigsten in jeder Mainstream-Sprache. Für einfache Anwendungen ist sie vielleicht sogar die einzige Bibliothek, die Entwickler:innen brauchen. Von der String Manipulation bis hin zu einem kompletten HTTP-Client und -Server verfügt die Go-stdlib über eine große Anzahl Funktionalitäten. Die Sprache und die stdlib bieten Entwickler:innen bereits jede Menge Möglichkeiten. Aber erst die zahlreichen Entwicklerwerkzeuge, die Go bereitstellt, machen die Sprache so attraktiv. Diese Tools folgen ebenfalls der Go-Philosophie der Einfachheit und Standardisierung. Mit go fmt können Entwickler:innen eine konsistente und standardisierte Formatierung in einer Go-Codebasis verwenden. go get macht die Paketverwaltung einfacher und schneller, da man damit Pakete und Abhängigkeiten herunterladen und installieren kann. go doc bietet Entwickler:innen schnellen und einfachen Zugriff auf die Dokumentation. Und go test fördert Praktiken wie die testgetriebene Entwicklung (TDD).
Die Kombination aus Sprache, stdlib und Werkzeugen macht Go zu einer wirklich produktiven Sprache für Entwickler:innen. Ihr Fokus auf Standardisierung und Einfachheit ermöglicht es, dass sich Entwickler:innen mehr auf das Ausliefern neuer Funktionalitäten konzentrieren können, statt sich mit Kleinigkeiten wie der Formatierung oder dem Testwerkzeug aufzuhalten.
Go ist nicht nur ein Gewinn für Entwicklererfahrungen. Es bietet Entwickler:innen zum einen angenehme und effiziente Arbeitsabläufe und überzeugt zum anderen auch durch seine Leistung. Die Fähigkeit von Go, direkt in Binärdateien zu kompilieren, lässt sie im Vergleich zu interpretierten Sprachen wie Python oder Ruby um Längen voraus sein. Sie ist schnell genug, um es mit JVMs aufnehmen zu können, und das auf elegante Weise, ohne eine zusätzliche Laufzeitumgebung mit sich zu bringen. In der pulsierenden Welt der Containerisierung und des Edge-Computings ist diese Effizienz nicht nur nice-to-have, sondern ein echter Gamechanger.
Die reine Ausführungsleistung ist zwar wichtig, aber sie ist nicht allein ausschlaggebend. Geschwindigkeit ist hier nicht der einzige Faktor, Leistung bedeutet auch intelligentes Multitasking. Hier kommen goroutinen und channels ins Spiel: Gos leichtgewichtige, schnelle Threads, die die Laufzeitumgebung mit Bravour handhabt. Das ist nicht nur eine Verbesserung, sondern revolutioniert die Art und Weise, wie Entwickler:innen nebenläufige Programme schreiben. Goroutinen machen komplexe Aufgaben lösbar und ermöglichen es Entwickler:innen, skalierbare und effiziente Anwendungen zu erstellen, ohne dabei ins Schwitzen zu geraten. Gerade in der schnelllebigen Welt der Webanwendungen, in der das Jonglieren mit mehreren Anfragen das A und O ist, verschafft dies den Entwickler:innen einen großen Vorsprung, wenn es um umfangreiche Webanwendungen geht.
Go hat sich deshalb auch im Bereich der Webanwendungen etabliert. Dort wird es vor allem genutzt, um leistungsstarke und skalierbare REST-, GraphQL- oder GRPC-Endpunkte zu erstellen.
Wie bei jeder Backend-Lösung werden API-Endpunkte typischerweise über eine Client-Anwendung kommuniziert, die in der jeweils populären Javascript-Variante geschrieben ist, und das funktioniert unbestreitbar gut. Allerdings bietet Go, gestützt auf die oben beschriebenen Funktionen, mehr Flexibilität für alternative Frontend-Architekturen. Moderne Unternehmensanwendungen müssen auf immer mehr Geräten, mit verschiedensten Bildschirmen oder auch ohne Bildschirme, mit diversen Frontend-Anwendungen, in unterschiedlichen Nutzungskontexten und in Anwendungen von Drittanbietern gut funktionieren. Deshalb kommen jetzt immer mehr Backend-for-Frontend-(BFF)-Muster oder -Architekturen zum Einsatz: Unternehmen haben oft getrennte APIs, die für verschiedene Frontend-Anwendungen optimiert sind. Sie nehmen häufig gerätespezifische Verarbeitungen/Vorverarbeitungen vom Client zurück auf die Backend-API.
Die Trennung von APIs in einer BFF-Architektur ist eine absolut geniale Lösung, die die Einführung von Funktionen erheblich vereinfacht. Das Beste daran ist, dass nicht mehr ein komplexer API-Release-Zyklus für unterschiedliche Client-Apps und -Geräte verwaltet werden muss. Außerdem kann man damit die Leistung optimieren und Funktionen, Updates und Fehlerbehebungen innerhalb der API implementieren. So muss man User:innen nicht dazu bringen, die Client-Software zu aktualisieren. Und auch, was die Fehlertoleranz angeht, ist das Abschalten einer bestimmten API eine gute Lösung. Damit lassen sich app- oder gerätespezifische Probleme wie Bugs oder DDoS-Angriffe beheben, ohne dass die Anwendung für alle Nutzer:innen abgeschaltet werden muss. Go ist perfekt für die Entwicklung und Pflege von schnellen, sauberen, anwendungsfallorientierten APIs. Und wie wir weiter unten sehen werden, ist es auch ideal für die BFF-Implementierung, weil es eine klare Architektur hat, die durch das richtige Unternehmensframework gefördert wird. Für Unternehmen, die noch mehr wollen, kann Go Entwickler:innen sogar in die Lage versetzen, vollwertige Webanwendungen zu erstellen. Dank ihrer Leistungsvorteile können Go-Entwickler:innen voll funktionsfähige serverseitige Webanwendungen designen, die genauso leistungsfähig und skalierbar sind wie jede Javascript-Anwendung, die mit einer API kommuniziert. Das heißt, dass ein Unternehmen nicht mehr zwei verschiedene Teams für Backend und Frontend unterhalten muss, die beide mit völlig unterschiedlichen Tools, Sprachen und oft auch Bereitstellungsmethoden arbeiten.
Für Teams, die diesen Ansatz verfolgen, kann sich die Geschwindigkeit der Produktinnovation massiv erhöhen, weil es kein „Hin und Her” mehr zwischen Backend-API-Funktionen und Front-End-Integration gibt. Ein Team macht beides. Bis vor kurzem hätte man das noch als ziemlich altmodisch angesehen. Vielleicht ist es das auch, aber die zunehmende Beliebtheit von Tools wie Hotwire oder HTMX zeigt, dass etwas zwar „altmodisch” sein mag, aber dennoch einen wertvollen Ausgangspunkt für moderne Innovationen bieten kann. Wenn Du Go als Front- und Back-End-Sprache verwendest, kannst Du alle Vorteile von Go nutzen, ohne auf Funktionen verzichten zu müssen. Der Nachteil dieses Front-to-Back-Ansatzes ist, dass das betreffende Go-Projekt sehr groß wird und eine breitere Funktionsvielfalt enthalten muss. Das lässt sich zwar durch die Verwendung der mächtigen Go stdlib lösen, aber ist das wirklich sinnvoll? Irgendwann kommt hier dann der Zeitpunkt, an dem sich das Entwicklerteam mit einem der polarisierendsten Begriffe in der Go-Gemeinschaft beschäftigen muss – dem Framework.
Sobald die Anwendungen produktiv laufen, legt die Design-Philosophie von Go den Schwerpunkt auf Leistung und Effizienz, was zu einer Verbesserung des Ressourcen-Managements mit Verringerung des Overheads sorgt. Das liegt daran, dass Go kompiliert ist. Anwendungen werden direkt in Maschinencode umgewandelt, den die Hardware ausführen kann. Im Gegensatz zu Python oder PHP, die während der Laufzeit interpretiert werden. Das führt zu deutlich schnelleren Ausführungsgeschwindigkeiten und geringeren Latenzzeiten – ein entscheidender Vorteil bei Echtzeit-Anwendungsszenarien.
Außerdem können Entwickler:innen dank der stabilen Standardbibliothek von Go und der einfachen Handhabung von Nebenläufigkeit mit goroutinen hoch skalierbare und leistungsfähige Anwendungen mit geringerer Komplexität schreiben. Im Gegensatz zu Python kann Go in Multi-Thread-Anwendungen nicht zum Engpass werden. PHP hat traditionell kein eingebautes Modell für Parallelität und verlässt sich stattdessen auf Multiprocessing oder Erweiterungen wie pthreads.
Beim Deployment ist die statische Binärkompilierung von Go sogar ein Paradigmenwechsel. Jede Go-Anwendung wird in eine einzige Binärdatei kompiliert, die sämtliche Abhängigkeiten enthält. Das macht den Bereitstellungsprozess deutlich einfacher, weil keine Abhängigkeiten zur Laufzeit verwaltet werden müssen. Im Gegensatz zu Python- oder PHP-Anwendungen, die eine bestimmte Laufzeitumgebung oder auf dem Server installierte, externe Abhängigkeiten erfordern können.
Diese Eigenschaft von Go passt perfekt zu den in Docker und Kubernetes verwendeten Prinzipien der Containerisierung. Da Go-Binärdateien weniger Platz brauchen, starten sie schneller und es gibt weniger Overhead bei der Skalierung von Anwendungen über Container und Dienste in einem Kubernetes-Cluster. Die einfache Bereitstellung dieser kompakten, in sich geschlossenen Binärdateien rationalisiert die Pipelines für die kontinuierliche Integration und Bereitstellung (CI/CD) und erhöht die Gesamtproduktivität und Zuverlässigkeit der Bereitstellungszyklen.
Hat Dir unser Blogbeitrag „Die Wahl der Programmiersprache“ gefallen? Dann sei gespannt, wenn es nächste Woche mit dem zweiten Teil „Pro/Contra Development Frameworks“ weitergeht. Natürlich darfst Du auch den dritten Teil „Einführung in Flamingo“ nicht verpassen! Falls Du in der Zwischenzeit Fragen hast, kannst Du Dich gerne hier an unser AOE-Entwicklungsteam wenden.