Warum verwenden wir nicht GraphQL?

17.09.2024,

Bei drunomics bauen wir seit mehr als fünf Jahren Decoupled Drupal-Websites. Während dieser Zeit war GraphQL, dank des gut gewarteten GraphQL-Moduls, stets eine beliebte Wahl bei professionellen oder Unternehmensprojekten. Dennoch haben wir uns, obwohl es für Kunden auf den ersten Blick oft attraktiv erscheint, gegen die Verwendung von GraphQL entschieden. In diesem Blogbeitrag möchte ich zusammenfassen, warum wir GraphQL nicht verwenden:

Allgemeine Komplexität

GraphQL ist nicht nur eine neue Abfragesprache, die sowohl von Frontendern als auch Backendern erlernt werden muss. Das Backend muss darüber hinaus jede Art von Abfragen unterstützen, die die Frontender erstellen. Auf der Frontend-Seite werden zudem zusätzliche Bibliotheken und Werkzeuge zur Verarbeitung des Protokolls benötigt.

Lose Schnittstellenvereinbarung

GraphQL verleiht Frontend-Entwicklern weitreichende Befugnisse, doch dies um den Preis einer undefinierten oder sehr lose definierten Schnittstellenvereinbarung bzw. eines Datenmodells oder – präziser ausgedrückt – eines darauf aufgesetzten GraphQL-Schemas. Auf Basis dieser losen Schnittstellenvereinbarung ist es dem Frontend möglich, beliebige Abfragen zusammenstellen, die das Backend unterstützen muss, was uns direkt zum nächsten Punkt führt: 

Komplexe Abfragen

Wenn das Backend das Drupal-Datenschema direkt exponiert, werden potenziell viele Dinge ungewollt offengelegt, und Änderungen möglicherweise schwierig, denn: Wer weiß, welche Dateneigenschaften das Frontend nutzt und abfragt? Eine universelle Optimierung für sämtliche Anwendungsfälle zu erreichen, ist generell ein schwieriges Unterfangen.

Allerdings kann das Backend sein eigenes GraphQL-Schema zusammenstellen und genau jenes Datenmodell bereitstellen, das vom Client, dem Frontend, benötigt wird. Das ist in der Tat eine großartige Option, sie erfordert aber zusätzliche Arbeit und Code, um zwischen dem Schema und dem dahinterliegenden realen Datenmodell zu übersetzen. Es ermöglicht, das zugrundeliegende Datenmodell und Schema-Mapping zu ändern, während man bei der gleichen oder kompatiblen GraphQL-Ausgabe bzw. -Schema bleibt. Aber ist dieser Code, der das Mapping durchführt, leistungsfähig genug? Funktioniert er korrekt? Das ist, ohne genau die Abfragen zu kennen, für die man optimieren und testen muss, ziemlich schwer zu sagen. Und so wird der Prozess komplexer und komplexer.

Performance

Allem voran ist GraphQL nachteilig für Caching-Prozesse, da es POST-Anfragen verwendet. Der typische Workaround besteht darin, verkürzte, gehashte Abfragen zu verwenden und über GET-Anfragen darauf zuzugreifen, was dazu beitragen kann, das Problem zu mildern. Dies geschieht jedoch auf Kosten der Verknüpfung der eingesetzten Frontend- und Backend-Versionen, wodurch die Komplexität des Gesamtsystems als auch des Deployments erhöht wird. Auf diese Weise geht der Hauptvorteil von GraphQL - die Flexibilität im Frontend - verloren. Dies stellt also keinen einfachen oder zufriedenstellenden Kompromiss dar.

Client-seitige Datenabfrage

Mit GraphQL wird vom Webbrowser (oder allgemein dem Client) eine Abfrage an den Server gesendet, die exakt die benötigten Daten spezifiziert. Während dies einerseits dazu beitragen kann, die Nutzlastgröße zu reduzieren, setzt es andererseits den Client in die Steuerposition. Das führt oft zu zusätzlich erforderlichen Kommunikationsrunden, sprich basierend auf der ersten Anfrage werden häufig zusätzliche Daten für die Darstellung benötigt. Diese zusätzlichen Daten müssen oft über weiteren Anfragen abgerufen werden, was zusätzliche oder mehrere Kommunikationsvorgänge mit dem Server erfordert und dadurch die Latenz erhöht.

Im Gegensatz dazu kann der Server, wenn er sich in der Steuerposition befindet, effizient sämtliche Abfragen durchführen, zusätzliche Daten auflösen und in der Folge die resultierenden Daten einmalig über das langsamere Netzwerk senden.

Sicherheit

Unzureichend abgesicherte GraphQL-Abfragen können zur Preisgabe sensibler Daten führen. Zwar lässt sich dieses Risiko durch geeignete Authentifizierungs- und Autorisierungsmechanismen minimieren, jedoch gestaltet sich dies komplex, da der Server die konkreten Abfragebedürfnisse der Clients nicht im Voraus kennt, und so jede mögliche Kombination behandeln muss, die ein Client anfordern könnte. Leider ist es für Hacker in der Regel ziemlich einfach, absichtlich rechnerisch sehr aufwändige (GraphQL-)Abfragen zu schreiben und an den Server zu senden, wodurch die Tür für DDOS- oder sogar DOS-Angriffe geöffnet wird. 

Abgesehen davon wird aufgrund der Komplexität des Backends, das alle möglichen Kombinationen berücksichtigen muss, die Gefahr einer versehentlichen Datenleckage recht hoch. 

Conclusio

GraphQL bringt gewisse Herausforderungen mit sich, die jedoch in der Regel bewältigt werden können. Diese stellen einen vertretbaren Kompromiss dar, sofern die gebotenen Vorteile den zusätzlichen Aufwand rechtfertigen. Ist es also eine gute Idee, GraphQL zu verwenden? Es ist, wie so häufig, eine Frage des Kontexts. Meiner Erfahrung nach sprechen die Gründe jedoch öfter dagegen als dafür. 

RESTful als Alternative

Eine RESTful API stellt eine gängige Alternative zu GraphQL dar. Wie üblich bietet Drupal dahingehend mehrere gute Optionen:

  • Drupal bietet die JSON-API bereits in der Standardinstallation an – eine beachtliche Funktionalität. Obwohl diese in bestimmten Anwendungsfällen überzeugt, unterliegt sie dennoch einigen der zuvor erörterten Einschränkungen, wobei besonders die “Client-seitige Datenabfrage” und die “Lose Schnittstellenvereinbarung” hervorzuheben sind.
  • Durch die Nutzung der Drupal-API können Entwickler benutzerdefniniert RESTful-Endpunkte für Clients bereitstellen. Dieser Ansatz adressiert zwar sämtliche angesprochenen Problempunkte, erfordert jedoch für jede Funktionalität entsprechenden Entwicklungsaufwand im Backend sowie insbesondere eine durchdachte Konzeptionsphase. Dies geht zu Lasten der Flexibilität der Frontend-Entwickler, was übrigens genau der Grund ist, warum GraphQL so geschätzt wird!
  • Konfigurierbare RESTful-Endpunkte: Um den Entwicklungsprozess zu verbessern und Flexibilität im Frontend zu gewinnen, haben wir eine Lösung entwickelt, die benutzerdefinierte RESTful-Endpunkte bereitstellt, die über Drupal von Frontend-Entwicklern konfiguriert werden können. Dafür haben wir das Custom Elements-Modul verbessert, das Teil von Lupus Decoupled Drupal ist, sodass es sich in das Konfigurationssystem von Drupal integriert und eine Benutzeroberfläche zur Anpassung der Ausgabe nach Entity-Anzeigemodus bietet. Auf diese Weise können wir in vielen Situationen alle Anforderungen erfüllen und gleichzeitig dem Frontend-Entwickler ermöglichen, effizient zu arbeiten. Ich werde später in einem separaten Blogbeitrag weitere Details über die neue Custom Elements-Benutzeroberfläche teilen. (Update: Den Blogbeitrag finden Sie hier.) 

More articles

Alte Münze - "There are far better things ahead than any we leave behind"

Was mir das DrupalCamp Berlin über “Volunteering” beigebracht hat

Community14. November 2024
Vom Zögern zur Begeisterung: Als ich mich entschloss, beim DrupalCamp Berlin als Volunteer zu helfen, wusste ich nicht, was mich erwartet. Im Nachhinein war es eine unvergessliche Erfahrung, die mich tief in die Community eintauchen ließ. In meinem Bericht teile ich Einblicke hinter die Kulissen und was es wirklich bedeutet, ein Event wie dieses mitzugestalten.