Wege durch den REST-API-Dschungel mit GraphQL - Verschlungene Wege
←
→
Transkription von Seiteninhalten
Wenn Ihr Browser die Seite nicht korrekt rendert, bitte, lesen Sie den Inhalt der Seite unten
FACHTHEMA Verschlungene Wege Wege durch den REST-API-Dschungel mit GraphQL Frank Pientka Viele Dienste werden heute über eine REST-Schnittstelle ange- boten. Weil diese Dienste jedoch von unterschiedlichen Konsu- menten mit eigenen Bedürfnissen verwendet werden, gibt es un- terschiedliche Anforderungen daran. Da GraphQL nicht nur eine standardisierte Abfragesprache bietet, sondern auch eine Mög- lichkeit, verschiedene Datendienste zu einem neuen Dienst zu kombinieren, ermöglicht gerade ein föderiertes GraphQL, Ände- rungen an den beteiligten Schnittstellen zu verstecken und sich auf die fachlich wirklich wichtigen Daten zu konzentrieren. Der Erfolg vieler auf dem Internet basierender Geschäftsmodelle fußt auf einer API-Ökonomie rund um eine Plattform. Doch auch modernere Content-Management oder Shop-Produkte sind von vor- nerein als „headless” konzeptioniert. Dadurch wird es einfacher, diese zu integrieren oder an die wachsenden Ansprüche einer re- Abb. 1: Mehrere Quellen und unterschiedliche Clients sponsiven Oberfläche anzupassen und den Zugriff über die unter- schiedlichen Kanäle einzubinden. Daten beim Server anfordern muss. Gleichzeitig sind die Graph- Oft werden diese APIs als REST-Schnittstelle angeboten. Mit QL-Abfragen stark typisiert, sodass hier Fehler wie bei reinen GraphQL und OpenAPI existieren inzwischen Standards, die die JSON-basierten REST-Anfragen früher vermieden werden können. Einbindung, das Testen und die Qualitätssicherung der Schnitt- Mit GraphQL können unterschiedliche Backendsysteme für die An- stellen vereinfachen. ThoughtWorks hat GraphQL schon seit ein forderungen von unterschiedlichen Clients zur Verfügung gestellt paar Jahren in seinen Technology-Radar aufgenommen. Gleichzei- werden (s. Abb. 1). Dadurch ist GraphQL eine Alternative zu den tig warnt ThoughtWorks, ähnlich wie bei den API-Gateways, davor, Gateway- und Backend-for-Frontend-Mustern, ohne sich zunächst die Nutzung von GraphQL zu überfrachten. Deswegen sollte man an eine konkrete Implementierung zu binden. Das macht Graph- sich mit den Chancen und Risiken dieser Open-Source-Datenabfra- QL auch für Frontend-Entwickler attraktiv, da diese loslegen kön- ge- und Manipulationssprache beschäftigen. nen, sobald das Schema vorliegt und hier Mocktestdaten zur Ver- Ein großer Vorteil von GraphQL ist die mögliche Schema-Evo- fügung gestellt werden, bevor diese komplett umgesetzt oder die lution und dass der Client nur die von ihm benötigten Felder und Backendsysteme angebunden sind. 42 JavaSPEKTRUM 2/2021
FACHTHEMA Frank Pientka ist seit mehreren Jahrzehnten in der professionellen Softwareentwicklung tätig, aktu- Die Referenzimplementierung für Java ist GraphQL-Java ell als Principal Software Architect [ GraphJava]. Dieses wird auch für die GraphiQL Java Tools und bei der Materna SE in Dortmund. Als den GraphQL Starter for Spring Boot [GraphJava] verwendet. Gründungsmitglied des iSAQB liegt Auch für Micro-Profile gibt es Implementierungen für die eigene ihm das Lernen und Vermitteln von GraphQL-Spezifikation 1.0 [MICGRAPH]. Diese wird zum Beispiel guten Design-Prinzipien für mehr über SmallRye in OpenLiberty, WildFly oder Quarkus umgesetzt. Qualität in der Software am Herzen. Inzwischen gibt es eine Stiftung [GraphFnd], die sich nicht nur E-Mail: frank.pientka@materna.de um die Weiterentwicklung der Spezifikation [GraphSpec], sondern auch um die Verbreitung von GraphQL kümmert. Neben speziali- sierten GraphQL-Anbietern, wie Apollo und Hasura, arbeiten in der Wofür GraphQL? Stiftung viele namhafte Firmen, wie IBM, AWS und neo4j, mit [Gra- phLand], was die Bedeutung des GraphQL-Standards unterstreicht. GraphQL steht für „Graph Query Language” und wurde ursprünglich Der grundsätzliche Unterschied zwischen REST und GraphQL ist, von Facebook entwickelt. Seit 2015 werden die GraphQL-Spezifika- wer bestimmt, was ausgeliefert wird. Bei REST stehen die Anfor- tion [GraphSpec] (aktuell das Release June 2018 unter dem Open derungen einer Ressource im Vordergrund und der Client kann nur Web Foundation Agreement, OWFA v1.0.) und die zugehörigen Un- über das Auslieferungsformat, aber nicht über den Inhalt entschei- terprojekte von der GraphQL Foundation [GraphFnd], die zur Linux den. Bei GraphQL hingegen kann er entscheiden, welche Felder Foundation gehört, weiterentwickelt. Ein wichtiges Unterprojekt aus einem veröffentlichten Schema angefragt und zurückgegeben dabei ist das GraphiQL-Entwicklerwerkzeuge-Projekt, das sich um werden sollen (s. Abb. 3). Die REST-Aufrufe sind meist zwischen das GraphQL Language Server Protocol und Plug-ins für verschie- Microservices in einem LAN-Netz optimiert (Ost-/West-Kommuni- dene IDEs kümmert. Naturgemäß wird JavaScript (ebenso als Re- kation), hingegen weniger mit Nord-/Süd-Kommunikation zu ver- ferenzimplementierung) am besten unterstützt. Doch sowohl für schiedenen Clients in eher unzuverlässigen Netzen mit geringen den Server als auch den Client gibt es verschiedene Implementie- Bandbreiten. Das hat bei typischen REST-Aufrufen ein Over- und rungen in mehreren Programmiersprachen [GraphCode] und Pro- Under-fetching zur Folge. Was bedeutet, dass der Benutzer oft zu dukten. lange auf die Ergebnisse warten muss und zu viele unnötige Da- Abbildung 2 gibt einen groben Überblick über die Graph- ten mit mehreren statt einer gezielten Abfrage übertragen werden QL-Stiftungsmitglieder (AWS, IBM, Facebook, Twitter, PayPal, müssen. Airbnb, Shopify, neo4j), -Werkzeuge und -Produkte. Die am wei- Vorteile von GraphQL testen verbreiteten Produkte sind – neben dem Altair Editor – APIs haben ein stark typisiertes Schema der Apollo-Server, Hasura als GraphQL-Server für Datenbanken (PostgreSQL, mySQL, MS SQL), das Relay-Framework für React Kein Over-fetching (zu viele, unnötige Daten) bzw. Under-fetching (zu viele Aufrufe, um das gewünschte Ergebnis zu erhalten) und AWS AppSync und Amplify. Inzwischen gibt es nicht nur für viele IDEs, sondern auch für beliebte Testwerkzeuge, wie Linter Schema Stitching oder Föderation: kombinieren mehrerer APIs und JMeter, Introspektion-GraphQL-Scanner für die Burp-Suite Client bestimmt Ergebnis vs. Server sendet alles und Postman [POSTMAN] eine GraphQL-Unterstützung. Es gibt API-Evolution, das Schema kann erweitert werden, ohne dass die sogar eine OWASP GraphQL-Checkliste [OWASP], um typische Si- Clients daran angepasst werden müssen cherheitsfallen mit GraphQL zu vermeiden. Wer sich in der Apol- Subskription von Datenänderungen, es kann der Client darüber lo-Welt bewegt, findet in der Cloud mit dem Apollo Studio eine informiert werden komfortable, aber kostenpflichtige Lösung, die sogar eine Re- Seitenweises Lesen (Paginierung über Parameter) ist möglich gistry und die Messdaten des Apollo-Servers an einer Stelle in- tegriert. Tabelle 1: Vorteile von GraphQL gegenüber OpenAPI Abb. 2: GraphQL Foundation Landschaft [GraphLand] www.javaspektrum.de 43
FACHTHEMA Hier ist es hilfreich, dass GraphQL-Server, wie Apollo, die Möglichkeiten des Monitorings bieten, um sich bei der Optimie- rung auf die häufigsten oder die langsamsten Abfragen zu kon- zentrieren, wodurch man die Gesamtperformanz optimieren kann. Doch auch für Spring Boot gibt es Möglichkeiten, einfache Metriken abzufragen oder ein Abb. 3: Ressourcen vs. Schema orientiert Tracing einzubauen. Für das effiziente Arbeiten Tabelle 1 fasst die Vorteile von GraphQL gegenüber OpenAPI mit GraphQL hat Apollo zehn Prinzipien (angelehnt an die 12 Fac- zusammen. Ein Nachteil von GraphQL gegenüber OpenAPI ist der tor App von Heroku) erstellt [PRINC]. Diese lauten: größere Aufwand für die Implementierung der Abfrage und Up- 1. Nur ein unifizierter, konsistenter und stabiler Graph statt vie- date-Logik. Außerdem benötigt man spezialisierte Clients und ler. Bibliotheken, um mit GraphQL arbeiten zu können. Hier hat REST 2. Verteilte Implementierung des Graphen, sollte in den einzel- weniger Anforderungen, aber auch mehr Freiheiten, was eine Go- nen Fachdomänen stattfinden. vernance schwieriger macht. 3. Das GraphQL-Schema sollte zentral in einem Register zur Ver- Wie bei jeder guten Programmierschnittstelle sollte man auch fügung gestellt werden, als einzige zentrale „Quelle der Wahr- bei GraphQL vermeiden, zu viel von den internen Implementie- heit“. rungsdetails nach außen zu geben, da das sowohl die Nutzung als 4. Das Schema sollte die Implementierung abstrahieren, aber ge- auch die Anpassbarkeit und Austauschbarkeit der Implementierung nügend flexibel für den Nutzer sein. erschwert. Ein großer Vorteil, gerade wenn viele Clients mit un- 5. Das Schema soll sich inkrementell weiterentwickeln können. terschiedlichen Anforderungen die Schnittstelle nutzen, liegt da- 6. Die Performanz soll inkrementell verbessert werden. rin, dass Sie Ihre Abfragen an den Bedarf anpassen können, ohne 7. Der Graph soll ausreichend Metadaten für die Introspektion dass am Server etwas geändert werden muss. Insbesondere bei der durch die Entwickler zur Verfügung stellen. mobilen Nutzung erhält man hier mit weniger Abfragen und einer 8. Zugriffsrechte sollten pro Client vergeben werden. reduzierten Rückgabemenge schneller die wirklich benötigten Da- 9. Strukturiertes Logging der Graph-Abfragen, für bessere Opti- ten, was bei langsamen Verbindungen ein großer Vorteil ist. mierung und Fehlererkennung. 10. Aufteilung der GraphQL-Schichten in mehrere Unterschichten. Was ist zu beachten? Herausforderungen dezentraler Datenhaltung – Um REST-APIs zu verwenden, gibt es nicht den einen „richtigen“ Ansatz. Es ist auch ein Unterschied, ob jedes Projekt diese Ent- vom Flickenteppich zur Föderation scheidungen autonom trifft oder es hier Unternehmensvorga- Diese zehn Prinzipien werden besonders wichtig, wenn man Graph- ben gibt. Auch wenn die Umsetzung eines REST-Diensts mit vie- QL an vielen Stellen und Diensten einführen möchte. Ein Problem len Programmiersprachen möglich ist, lohnt es sich bei verteilten von vielen Mikrodiensten [NETFLIX] ist, dass diese oft für operati- Diensten, sich auf einen einheitlichen Beschreibungsstandard, wie onale Anwendungsfälle entwickelt wurden, jedoch für analytische OpenAPI oder GraphQL, zu einigen. Das macht vor allem das Sche- Abfragen eher wenig geeignet sind. ma- und Versionsmanagement erheblich einfacher. Weil für Berichte oder Auswertungen jedoch oft die Daten aus Traditionell kommt bei Alt- oder Fremdanwendungen oft das mehreren Domänen kombiniert werden müssen, muss hier eine Adapter- oder Gateway-Muster zum Einsatz. Dieses hilft den Nut- weitere Infrastrukturebene eingeführt werden, um die verteilten zern, sich von funktionalen Änderungen des Dienstanbieters et- Daten wieder in einen Datensee einzufangen und zu konsolidie- was zu entkoppeln oder nur die Nutzung auf ausgewählte Felder ren. Das führt jedoch oft dazu, dass hier ein größerer Integra- zu konzentrieren. Andererseits muss so eine zentrale Komponen- tions- und Datenqualitätssicherungsaufwand betrieben werden te, wie ein API-Gateway, wiederum separat verwaltet und be- muss, um die verschiedenen Domänenmodell miteinander syn- trieben werden, was die Vorteile eines möglichst unabhängigen chron zu halten. Im strategischen DDD-Design gibt es hierzu eini- Microservice etwas einschränkt. Ein GraphQL-Server ist hier flexi- ge Ansätze, doch wäre es hilfreich, solche Anforderungen gleich bler als klassische Gateway-Produkte. Ein großer Nachteil bei ei- innerhalb der Domäne zu berücksichtigen. So einen Ansatz möch- ner starken Nutzung ist die Skalierbarkeit und Ausfallsicherheit. te die noch neue DataMesh-Disziplin [DAT20] bieten. Ziel ist, Hier kann sich der einzelne GraphQL-Server schnell zum Engpass dass von einer Domäne auch analytische Schnittstellen angebo- entwickeln. ten werden, die zusammen zu neuen Diensten flexibel kombiniert Die Flexibilität der Abfragen hat auch Nachteile bei der Skalier- werden können. barkeit, da es schwieriger wird, Ergebnisse sowohl auf dem Client Einen ähnlichen Ansatz gibt es bei GraphQL schon. Das so- als auch auf dem Server zu cachen oder vorzuberechnen. Das ist genannte Stitching (Zusammennähen, [STITCH]) versucht, für bei reinen RESTvollen Diensten besser, erfordert jedoch auch ein bestehende GraphQL-Schemata ein besser passendes übergrei- anderes Abfrage- und Ergebnisdesign. Bibliotheken wie Relay oder fendes Schema zu definieren. In Abbildung 4 wird ein neues Apollo Client erleichtern das Arbeiten mit GraphQL und ermögli- Schema auf Basis der Felder der Schemata Filme, Produktion chen gleichzeitig auch, den Antwortgraphen effizient zu cachen. und Schauspieler zusammengestellt. Da dies rein deklarativ er- 44 JavaSPEKTRUM 2/2021
FACHTHEMA Abb. 4: Das Schema-Stitching am Beispiel folgt, muss hier kein zusätzlicher Transformationscode geschrie- Literatur und Links ben und bei Änderungen angepasst werden. Das erleichtert nicht nur die Umsetzung, sondern hilft auch, schneller an die Daten [aFEDER] Apollo Federation specification, heranzukommen. Dadurch dass jedes einzelne Schema sich un- https://www.apollographql.com/docs/federation/managed- abhängig voneinander weiterentwickeln kann, werden auch die federation/overview/, unterschiedlichen Anforderungen berücksichtigt, ohne sich ge- https://www.apollographql.com/docs/federation/federation- genseitig zu behindern. spec/, https://www.apollographql.com/docs/federation/ Ein Problem kann bei größeren Datenmengen die Performanz migrating-from-stitching/ sein, sodass einzelne Daten nur inkrementell geladen werden müs- [APOLLOj] Apollo Federation on the JVM, sen oder eine Vorberechnung (Resolver) eingeführt werden muss. https://github.com/apollographql/federation-jvm Ein typisches Problem wäre zum Beispiel eine Suche über mehrere [DAT20] Z. Dehghani, Data Mesh Principles and Logical Domänen. Hier können die Teilmodelle als eine neue Oberdomäne Architecture, 2020, https://martinfowler.com/articles/data- mit Schema präsentiert werden, ohne sich mit den Beziehungsde- mesh-principles.html, https://martinfowler.com/articles/data- tails zwischen den Modellen beschäftigen zu müssen. Selbst wenn monolith-to-mesh.html, s. a. https://www.thoughtworks.com/ sich die Teilmodelle ändern, muss nicht das Oberschema angepasst de/radar/techniques/data-mesh, https://www.thoughtworks. werden, sondern nur die daraus generierten Abfragen der Teilmo- com/insights/blog/data-mesh-its-not-about-tech-its-about- delle. ownership-and-communication Die verteilte GraphQL-Spezifikation [aFEDER] und ihre Umset- [GraphCode] GraphQL, Werkzeuge und Programmiersprachen, zung sind noch neu und eher für Abfragen als für Datenänderun- https://graphql.org/code/ gen geeignet. Neben dem Apollo-Server, der mit node.js läuft, [GraphFnd] GraphQL Foundation, gibt es mit Apollo Federation on the JVM [APOLLOj] eine Graph- https://foundation.graphql.org/ QL-Starter-Implementierungen für Spring Boot. Das erst vor Kur- [GraphLand] GraphQL Foundation Landscape, zem freigegebene Netflix-Framework Domain Graph Service (DGS) https://landscape.graphql.org/ [NETFDGS] für Spring Boot basiert auf graphql-java und soll mit [GraphSpec] GraphQL specification, Annotationen (Code-first) die Verwendung von verteilten Graph- https://github.com/graphql/graphql-spec QL-Diensten erleichtern. Hier wäre es zu wünschen, wenn es in Zu- [GraphJava] GraphQL Java implementation, kunft noch mehr Implementierungen geben würde, um von einem https://www.graphql-java.com/ unabhängigen Standard zu sprechen. [GraphJavaT] GraphQL Java Tools, GraphQL Starter for Spring Boot, https://www.graphql-java-kickstart.com [Hun17] M. Hunger, GraphQL mit Java, in: JavaSPEKTRUM, 4/2017 Fazit [MICGRAPH] MicroProfile GraphQL 1.0, Mit GraphQL gibt es eine implementierungsunabhängige Möglich- https://download.eclipse.org/microprofile/microprofile- keit, seine Daten zu beschreiben. Die Clients können mit unter- graphql-1.0/ schiedlichen Programmiersprachen umgesetzt werden und die von [NETFLIX] T. Shikhare, https://netflixtechblog.com/how-netflix- ihnen benötigten Daten optimal abfragen. Dabei sind die Clients scales-its-api-with-graphql-federation-part-1-ae3557c187e2, weniger von Erweiterungen des Schemas betroffen, sodass weniger 9.11.2020, und https://netflixtechblog.com/how-netflix- Anpassungs- und Abstimmungsaufwände nötig sind. Je mehr Fir- scales-its-api-with-graphql-federation-part-2-bbe71aaec44a, men nicht nur software-, sondern auch datengetrieben vorgehen, 11.12.202o werden APIs und ihre Daten immer mehr als Produkt angesehen. [NETFDGS] P. Bakker, K. Srinivasan, Netflix Domain Graph Service Dadurch wird auch der Bedarf nach einem DataMesh immer stärker (DGS) framework, https://netflixtechblog.com/open-sourcing- wachsen. the-netflix-domain-graph-service-framework-graphql-for-spring- Über die verteilte GraphQL-Spezifikation wird es möglich, ein boot-92b9dcecda18 vereinheitlichtes Schema für verschiedene Microservices anzu- https://netflix.github.io/dgs/ bieten, ohne dass diese selbst GraphQL sprechen. Bisher existie- [OWASP] OWASP GraphQL Cheat Sheet, https://cheatsheetseries. ren neben Apollo noch nicht so umfangreiche Implementierun- owasp.org/cheatsheets/GraphQL_Cheat_Sheet.html gen, die alle Funktionen des verteilten GraphQL abdecken. Doch [POSTMAN] Postman GraphQL support, mit der wachsenden Verbreitung von GraphQL und damit der zu- https://www.postman.com/graphql/ nehmenden Größe seiner Modelle wird der Bedarf zunehmen. [PRINC] Principled GraphQL, https://principledgraphql.com/ Deswegen lohnt sich auf jeden Fall ein Blick auf dessen neue Mög- [STITCH] Schema-Stitching, https://www.graphql-tools.com/ lichkeiten. docs/schema-stitching/ www.javaspektrum.de 45
Sie können auch lesen