Web-APIs mit GraphQL

Louis Kuhnt, 21. September 2023
Lesezeit: 15 Minuten

Die Entwicklung verteilter Systeme zur Bereitstellung von Client-Server-Kommunikation über REST(-ful)-API Services hat sich seit Jahrzehnten als Industriestandard etabliert und ist für die Mehrheit der Anwendungsfälle ausreichend. In jüngster Zeit ist jedoch eine signifikante Veränderung in der Softwareentwicklung zu beobachten. Klassische Webseiten, die lediglich für die Darstellung von Daten zuständig waren, werden zunehmend durch komplexe Client-Systeme mit eigener Geschäftslogik abgelöst. Dieser Umbruch erfordert eine Überprüfung und Anpassung der herkömmlichen API-Ansätze, um den wachsenden Anforderungen gerecht zu werden.

Meine Bachelorarbeit „Web-APIs mit GraphQL - Erarbeitung eines Leitfadens zur Migration von REST-Schnittstellen und die prototypische Anwendung anhand von ausgewählten Projekten“ , welche ich der avocado software engineering GmbH, im nachfolgenden avocado-se genannt, in den letzten 4 Monaten geschrieben habe, stellt mit einem Leitfaden zur Migration zu GraphQL eine zukunftsorientierte Alternative zum REST-Standard zur Verfügung.

Motivation

Die avocado-se arbeitet mit einem modernen Tech-Stack, dazu gehört auch die Nutzung von Single-Page-Application Frameworks wie Angular. Single-Page Applications sind interaktive Webseiten, die bei Datenänderungen und Interaktionen mit dem Benutzer dynamisch die bestehende Seite aufbauen können, ohne dass ein erneutes Laden der Webseite nötig ist. Solche Clients werden dann als Rich-Clients bezeichnet und brechen mit der Konvention, dass Programmlogik und Darstellung voneinander getrennt behandelt werden sollten.

Durch diesen dynamischen Aufbau treten die spezifischen Probleme des Under- und Overfetching von einer REST(-ful) API auf. Mit dem Ziel die Probleme zu tilgen und gleichzeitig die Ressourcen der Anwender zu schonen und unnötige Daten schon vor der Übertragung zum Client-System herauszufiltern, wurde GraphQL 2012 von Facebook entwickelt und später 2015 als Open-Source Projekt öffentlich gemacht.

Im Blog-Beitrag „Strapi-Content mit GraphQL einbinden“ wird die Manipulations- und Abfragesprache GraphQL ausführlich beschrieben, deswegen verzichtet dieser Beitrag auf Dopplungen in der Beschreibung.

REST vs GraphQL

Der Vergleich zwischen REST und GraphQL gibt nicht nur Auskunft über die Stärken und Schwächen der zwei Architekturen, sondern auch Hinweise auf mögliche Anwendungsgebiete.

Overfetching und Underfetching

Aufgrund der Struktur von REST, bei der viele Endpunkte spezifische Ressourcen bereitstellen, sind mehrere API-Aufrufe zur Darstellung komplexer Client-Aufbauten üblich. Diese Architektur birgt jedoch das Risiko, entweder zu viele Daten in einem einzigen Aufruf abzurufen und dadurch die Verbindung unnötig zu belasten oder für bestimmte Daten mehrere Ressourcen und somit mehrere Endpunkte aufrufen zu müssen. Das Problem des Overfetching und Underfetching wird durch eine Reduzierung auf einen GraphQL-Endpunkt gelöst. Dieser Endpunkt bietet die Möglichkeit, auf alle Ressourcen zuzugreifen und Daten mithilfe des Schemas konkret nach Anforderungen abzufragen.

Dokumentation

Durch die Verwendung eines Schemas, welches alle gegebenen Endpunkte und Entitäten zur Verfügung stellt, gilt GraphQL in Fachkreisen als selbst-dokumentierend. Der Nutzer der Schnittstelle hat durch das Schema immer den aktuellen Stand der zur Verfügung stehenden Ressourcen. Das Schema nimmt die Position eines Vertrages ein. Bei einer REST-Schnittstelle ist der Nutzer auf eine API-Dokumentation angewiesen.

Cache-Funktionalitäten

Die Caching-Funktionalität, welche in der REST-Architektur für das Zwischenspeichern wiederholter Anfragen benutzt und in den meisten Ebenen der Architektur verbaut ist, wird von der Schema-Definition und der GraphQL-Laufzeit nicht umgesetzt. Durch die Individualität der Anfragen auf Ressourcen, welche das Grundkonzept von GraphQL darstellt, ist eine Zwischenspeicherung nicht sinnvoll.

Das N + 1 Problem und Performance Limitierung

Das "N + 1"-Problem beschreibt einen Vorgang, bei welchem durch eine Abfrage stets weitere Abfragen gestartet werden, sodass die Anfrage in einer Endlosschleife stecken bleibt. Das Problem ist GraphQL spezifisch, da hierbei Rekursionen durch den Individuellen Aufbau der Anfragen erschaffen werden können. Bei der Performance kann auch eine GraphQL Schnittstelle der Schnelligkeit von REST in den meisten Fällen nichts entgegensetzen. Aber die Datenübertragung kann signifikant verringert werden.

Es ist wichtig zu erkennen, dass GraphQL nicht unbedingt als Ersatz für jede REST(-ful)-API gedacht ist, sondern vielmehr als eine Ergänzung zur bestehenden Architektur. Bei neuen Projekten ist der Einsatz von GraphQL in der Abfrage von Entitäten jedoch zu bevorzugen, da dieses architekturelle Fundament eine solide Grundlage für die zukünftigen Anforderungen von Rich-Clients und Consumer-Applications ausgelegt ist.

avocadoQL - Leitfaden und verwendete Technologien

Der in der Bachelorarbeit erläuterte Leitfaden „avocadoQL“ hat die Aufgabe, eine für erfahrene und unerfahrene API-Entwicklern gleichermaßen verständliche und effektive Migration von einer REST-API zu einer GraphQL-API bereitzustellen.

Um eine nachhaltige Migration zu ermöglichen, werden zunächst verschiedene sinnvolle Anwendungsfälle für Projekte aufgeführt und erläutert. Basierend auf dem Stand der Technologien, die bei avocado software engineering verwendet werden, wird eine Auswahl an Frameworks und Bibliotheken bereitgestellt. Diese Technologien werden entsprechend dem vorhandenen Tech-Stack bewertet. Die Vorbereitungen zielen darauf ab, den Entwicklern einen geeigneten Weg aufzuzeigen und die Migration somit greifbarer zu gestalten. Der Leitfaden bietet dem Entwickler schrittweise Anleitungen zur Migration des Servers und anschließend zur Migration des Clients.

/uploads/Blog_Leitfaden_6ae1c658dc.PNG

Die Technologien die für die Umsetzung der Architektur verwendet werden unterscheiden sich zwischen Client- und Server-Technologien. Der Client hat die Aufgabe die Anfragen umzuwandeln und zu senden, sowie die Antworten interpretieren. Der Server gibt das Schema frei und besitzt die Laufzeit der GraphQL-Schnittstelle. Auf der Client-Seite wird mit Apollo-Client im Zusammenspiel mit einer Code-Generierung gearbeitet. Der Apollo-Client ist für das Senden und Interpretieren des Schemas zuständig und die Code-Generierung erstellt aus dem Schema leicht in Angular anwendbare Befehlsstrukturen. Der Server gibt mithilfe von GraphQL-DGS das Schema frei, validiert die Anfragen und schneidet die Antworten zurecht. Die nachfolgende Abbildung zeigt den schemenhaften Ablauf einer Beispielabfrage.

/uploads/Blog_Ablauf_4f50a7401d.PNG

Leistungsvergleich

In meiner Bachelorarbeit wurden zwei APIs prototypisch von REST auf GraphQL migriert und anhand der Daten konnte ein Leistungsvergleich erstellt werden. Dabei wurden je nach Anwendungsfall verschiedene Ergebnisse geliefert. Im nachfolgenden gibt es für die zwei migrierten APIs jeweils zwei Leistungsindikatoren, zum einen die Antwortzeit und zum anderen die Byte-Größe der zurückgegebenen Server Antwort. Dabei geben die Szenarios die verschieden viele angefragte Daten an. Szenario 1 sind somit nur wenige einzelne Daten, wobei bei Szenario 3 das maximum an Daten der Entität angefragt wird.

/uploads/Groesse_Dormakaba_d3dd43e4d9.PNG

/uploads/Antwortzeit_Dormakaba_ee962180da.PNG

Bei Projekt 1 fällt eine signifikante Reduzierung der Datenmenge um durchschnittlich 23 % auf und eine Verlangsamung der Antwortzeit um 16 %.

/uploads/Groesse_Movarti_94b14dd64b.PNG

/uploads/Antwortzeit_Movarti_49deb374ca.PNG

Bei Projekt 2 verringert sich die Menge der übertragenen Daten um 99.63 % und die Anfrage wird um 10 % schneller ausgeführt.

Fazit

Das Hauptziel der Abschlussarbeit bestand darin, die avocado-se für zukünftige und aktuelle Anforderungen von Rich-Clients und Consumer-Applications mithilfe der GraphQL-Abfrage- und Manipulationssprache vorzubereiten. Dies wurde durch die Entwicklung eines umfangreichen Leitfadens namens avocadoQL erreicht, welcher die Besonderheiten und Architekturen der avocado-se in die Umsetzung des Leitfadens einbezieht. Ein weiteres Ziel bestand darin, die Leistungsfähigkeit dieser Laufzeitumgebung kritisch zu überprüfen und eine Abwägung zwischen der etablierten REST-Architektur und GraphQL vorzunehmen. Die Absicht war sicherzustellen, dass beide als Symbiose nebeneinander existieren können. So ist es für die Entwickler der avocado-se möglich, je nach Anwendungsfall eine REST(- ful)-Architektur oder eine GraphQL-Laufzeit zu benutzen.

author image
Louis Kuhnt
Absolvent der Hochschule Furtwangen
Durch die wissenschaftliche Arbeit, welche ich in der avocado software engineering die letzten 4 Monate bearbeitet habe, wurde ein tiefes Verständnis für API-Architekturen erlangt. Dabei habe ich mit zukunftsorientierten Technologien gearbeitet, die nun aktiv im Unternehmen eingesetzt werden.