Erhältlich ab: Februar 2017
Oft werden in Eclipse so genannte Texteditoren verwendet, d. h. Editoren, die den Quelltext direkt anzeigen, aber durch Syntax-Highlighting oder Code Completion die Arbeit erleichtern. Traditionell war das Erstellen von neuen oder eigenen Editoren in Eclipse relativ kompliziert. Die Eclipse-Plattform hatte eigentlich nur die Möglichkeit geboten, in existierenden Editoren zusätzliche Klasse zu registrieren, die neue Textbereiche als Hyperlinks identifizieren. Viele Projekte haben daher eigene Frameworks entwickelt, um Editoren erweiterbar zu machen. Projekte wie Eclipse WTP mit den Source-Editoren für XML oder das Mylyn-Projekt für Wiki-Sprachen wie AsciiDoc haben hier gute Lösungen für isolierte Probleme geschaffen.
In einer Zeit, in der neue Sprachen und neue Dateiformate recht schnell entstehen und auch wieder verschwinden, hat dieser Ansatz seine Nachteile. Das Entwickeln von Editoren „eben mal schnell“ war in Eclipse nicht einfach. Entwickler von Red Hat haben dieses Problem erkannt. Eclipse 4.7 wird einen Texteditor haben (Generic Editor), der erweiterbar sein wird. So kann man ihn als Basis für eigene Ergänzungen nutzen. Das macht die Unterstützung von neuen Sprachen und Features signifikant einfacher. Signifikant einfacher? Was soll denn das heißen? Na gut, wir schauen uns einmal ein Beispiel dazu an.
Wir probieren aus, wie schwer es ist, einen Editor für Gradle zu erstellen, der mindestens Syntax-Highlighting unterstützt. Das Beispiel basiert auf einem Vortrag von Sopot Cela auf der letzten EclipseCon Europe. Dort hat Sopot den Editor live während seines Vortrags programmiert. Als Erstes lädt man sich den neuen Milestone für Eclipse 4.7 herunter [1]. Dann erzeugt man ein neues Plug-in. Da Plug-in-Entwicklung schon in dieser Kolumne im Java Magazin 11.2016 beschrieben wurde, gehen wir hier nicht mehr im Detail darauf ein, sondern es werden nur die Besonderheiten für den Editor beschrieben.
Für unseren Gradle-Editor brauchen wir als Erstes einen Content Type, für den man den Editor später registrieren kann. Das geht u. a. über den Extension Point org.eclipse.core.contenttype.contentTypes. Interessant sind hier die file-extension und der base-type.
<extension point="org.eclipse.core.contenttype.contentTypes">
<content-type
base-type="org.eclipse.core.runtime.text"
file-extensions="gradle"
id="gradleeditorsupport.content-type3"
name="Gradle"
priority="normal">
</content-type>
</extension>
Dann legt man zwei kurze Klassen an. Die folgende Klasse definiert in unserem Beispiel die Schlüsselwörter, die per Syntax-Highlighting hervorgehoben werden sollen (Listing 1).
Listing 1: Klasse für das Syntax-Highlighting
package gradleeditorsupport;
import org.eclipse.jface.text.TextAttribute;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.IWordDetector;
import org.eclipse.jface.text.rules.Token;
import org.eclipse.jface.text.rules.WordRule;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Display;
public class GradleKeywordRule extends WordRule {
String[] tagWrods = new String[] { "android", "compileSdkVersion", "buildToolsVersion", "defaultConfig", "applicationId", "targetSdkVersion", "applicationId", "versionCode", "minSdkVersion", "versionName", "testInstrumentationRunner", "buildTypes", "release", "dependencies", "androidTestCompile", "minifyEnabled", "proguardFiles", "compile", "testCompile", "apply", "plugin", "launcherArgs" };
private IToken wordToken = new Token(new TextAttribute(new Color(Display.getCurrent(), new RGB(139,0,139))));
public GradleKeywordRule() {
super(new Detector());
for (String word : tagWrods) {
this.addWord(word, wordToken);
}
}
}
class Detector implements IWordDetector {
public boolean isWordStart(char c) {
return Character.isAlphabetic(c);
}
public boolean isWordPart(char c) {
return Character.isAlphabetic(c);
}
}
Die zweite Klasse ist dann der so genannte PresentationReconciler, der die Darstellung des Texts übernimmt. Hier werden die Schlüsselwörter registriert und es wird u. a. definiert, was ein Kommentar darstellt (Listing 2).
Listing 2: Klasse für die Darstellung des Texts
package gradleeditorsupport;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.TextAttribute;
import org.eclipse.jface.text.presentation.PresentationReconciler;
import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
import org.eclipse.jface.text.rules.IRule;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.NumberRule;
import org.eclipse.jface.text.rules.PatternRule;
import org.eclipse.jface.text.rules.RuleBasedScanner;
import org.eclipse.jface.text.rules.SingleLineRule;
import org.eclipse.jface.text.rules.Token;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Display;
public class GradlePresentationReconciler extends PresentationReconciler {
private IToken quoteToken = new Token(new TextAttribute(new Color(Display.getCurrent(), new RGB(139, 69, 19))));
private IToken numberToken = new Token(new TextAttribute(new Color(Display.getCurrent(), new RGB(0, 0, 255))));
private IToken commentToken = new Token(new TextAttribute(new Color(Display.getCurrent(), new RGB(0, 100, 0))));
public GradlePresentationReconciler() {
RuleBasedScanner scanner = new RuleBasedScanner();
IRule[] rules=new IRule[5];
rules[0] = new SingleLineRule("'", "'", quoteToken);
rules[1] = new SingleLineRule("\"", "\"", quoteToken);
rules[2] = new NumberRule(numberToken);
rules[3] = new PatternRule("//", null, commentToken, (char)0, true);
rules[4] = new GradleKeywordRule();
scanner.setRules(rules);
DefaultDamagerRepairer ddr = new DefaultDamagerRepairer(scanner);
this.setDamager(ddr, IDocument.DEFAULT_CONTENT_TYPE);
this.setRepairer(ddr, IDocument.DEFAULT_CONTENT_TYPE);
}
}
Jetzt muss der GradlePresentationReconciler nur noch mit dem Framework über die plugin.xml registriert werden.
<extension point="org.eclipse.ui.genericeditor.presentationReconcilers">
<presentationReconciler
class="gradleeditorsupport.GradlePresentationReconciler"
contentType="gradleeditorsupport.content-type3">
</presentationReconciler>
</extension>
Startet man eine neue Eclipse-Instanz mit diesem neuen Plug-in und öffnet eine .gradle-Datei via Open With | Generic Editor, hat man schon einen Editor mit Syntax-Highlighting (Abb. 1). Das war doch einfach, oder?
Unter [2] und [3] arbeiten Angelo Zerr und Mickael Istria an der Unterstützung für die populäre TextMate Grammar. Damit würde jede Sprache, die eine TextMate-Beschreibung hat, Syntax-Highlighting in Eclipse unterstützen. Der Plan ist, dass dies ab Eclipse 4.7 in die Eclipse-Downloads integriert wird. Damit ließe sich Eclipse für neue oder noch nicht in Eclipse unterstützte Sprachen nutzen – ähnlich wie Sublime, Atom und Emacs das heute schon können.
Um das Ganze noch einfacher zu machen, arbeiten Istria und Cela auch an der Unterstützung des Microsoft Language Server Protocols für den Generic Editor. Hier hat Microsoft ein JSON-basiertes Kommunikationsprotokoll entwickelt, mit dem Serverkomponenten mit Editoren sprechen können. Die lokal laufende Serverkomponente analysiert die Datei und schickt ein JSON zurück, das das Syntax-Highlighting, die Quick Fixes, die Tooltips und die Code Completion für die Datei liefert.
Da Microsoft dieses Protokoll in seinen Tools unterstützt oder unterstützen wird, ist hier breite Unterstützung in den Sprachen entweder schon vorhanden oder in Arbeit. Das Eclipse-JDT-Projekt arbeitet zurzeit an einer Serverkomponente, um die JSON-Daten für einen Java-Editor bereitzustellen. Aber auch andere Sprachen liefern gerade solche Serverkomponenten. Und die Eclipse-Nutzer werden auch von diesen Arbeiten profitieren, um mit Rust, Ruby, Scala oder für andere Sprachen zu entwickeln. Die Arbeiten werden im neuen Eclipse-LSP4E-Projekt durchgeführt [4].
Das Eclipse-Editorframework wird leichtgewichtiger, und es wird einfacher, von anderen Open-Source-Standards zu profitieren. Das sind sicherlich gute Nachrichten für die Eclipse IDE. Es wird immer mehr wiederverwendet, und es ist immer weniger notwendig, die Dinge selbst zu implementieren. Damit können Eclipse-User künftig direkt mit neuen Sprachen arbeiten und müssen nicht mehr ein bis zwei Jahre warten, bis jemand die Features in der IDE nachimplementiert hat.
Simon Scholz ist Eclipse Platform und e4 Committer und nutzt seine langjährige Eclipse-RCP- und Plug-in-Erfahrung für Kundenimplementierungen, Eclipse-RCP-Workshops und Schulungen. Zudem hält er regelmäßig Vorträge auf Softwarekonferenzen bezüglich verschiedener Eclipse-Technologien.
Lars Vogel ist Geschäftsführer der vogella GmbH, die Kunden im Bereich Eclipse, Android und anderen Themen unterstützt. Als Project-Management-Committee-Mitglied, Eclipse-Projektleiter und Committer hilft er dem Eclipse-Projekt.
[1] Eclipse Download: http://download.eclipse.org/eclipse/downloads/
[2] TextMate support in Eclipse IDE: https://projects.eclipse.org/proposals/textmate-support-eclipse-ide-textmate4e
[3] Bugtracking für das TextMate-Projekt: https://bugs.eclipse.org/bugs/show_bug.cgi?id=508557
[4] Eclipse-LSP4E-Projekt: https://projects.eclipse.org/projects/technology.lsp4e
Stellen Sie sich vor, es ist Fußball-Europameisterschaft. Da gibt es die klassischen Favoriten, mit denen jeder rechnet. Dass sie schon die Gruppenphase meist ohne Probleme überstehen, ist zwar nicht gesetzt, aber wenn sie es tun, dann heißt es: Naja, war doch klar. Und dann kommt plötzlich so eine Mannschaft wie die isländische um die Ecke: unerwartet gut, sympathisch, Erfolgsprognose aber ungewiss.
Warum ich Ihnen das erzähle? So ähnlich geht es mir mit Kotlin. Im letzten Jahr, etwa um diese Zeit, ist die erste Hauptversion der Programmiersprache erschienen. Seitdem begegnet sie mir immer häufiger. Sie ergänzt die Landschaft der JVM-Sprachen, gilt aber aktuell noch eher als Exot. Entwickelt wird sie übrigens im Hause JetBrains, die für ihre Entwicklungsumgebung IntelliJ IDEA bekannt sind.
Nun, was zeichnet Kotlin aus? Für alle die, die nicht alles auf eine Karte setzen möchten, ist die Interoperabilität mit Java erstmal ein guter Anknüpfungspunkt. Man kann beide JVM-Sprachen zusammen verwenden; Teile einer Anwendung, die in Java geschrieben sind, können durch neuen Code in Kotlin ergänzt werden. Der Vorteil? Kotlin verspricht kurze Kompilierzeiten und prägnanten Code. Es gibt aber natürlich auch Elemente, die sich nicht eins zu eins übersetzen lassen. Daher stellt Ihnen Alexander Hanschke im ersten Artikel unseres Kotlin-Schwerpunkts in neun Lektionen vor, wie man mit Exceptions, Nulls oder Objects umgehen sollte, damit alles reibungslos verläuft.
Auch in der Android-Entwicklung spielt Kotlin eine immer größere Rolle. Diese beleuchten wir im zweiten Teil dieses Schwerpunkts. Hier hat die Sprache quasi Heimvorteil: Denn wie Kotlin selbst kommt auch Android Studio von JetBrains – und das ist schließlich die Standard-IDE zum Schreiben von Android-Anwendungen.
Im letzten Jahr titelten viele Fachmedien, dass Kotlin der neue Java-Herausforderer sei. So weit würde ich nicht gehen. Java und Kotlin stehen nicht in direkter Konkurrenz.
Welche Sprache man nutzen möchte, das hängt von vielen Faktoren ab. Und natürlich gibt es neben Kotlin noch eine Vielzahl weiterer Alternativen für die JVM. Aber es ist ein frischer Ansatz, Dinge neu, anders zu machen. Einen kleinen, nicht unwichtigen Aspekt dürfen wir hier nicht vergessen: Kotlin ist im Vergleich zu Java jung. Das kann ein Nachteil sein, denn es gibt wenige Erfahrungswerte. Aber es ist auch ein Vorteil: Schaut man auf historisch gewachsene – und teilweise leider verwucherte – Technologien, so erscheint Kotlin als ballastfreie Alternative.
Am Ende hat es die isländische Nationalmannschaft bis ins Viertelfinale geschafft. Das ist nicht der Pokal, aber ziemlich weit für einen Underdog. Mal sehen, wie weit Kotlin kommt.
In diesem Sinne, viel Spaß bei der Lektüre und huh, huh, huh!
Ohne Frage, REST hat sich in den letzten Monaten als Programmierparadigma für verteilte Systeme, wie Microservices oder Web-APIs, mehr als etabliert. Stark vereinfacht gesprochen, kann REST als Abstraktion der Struktur und des Verhaltens des WWWs gesehen werden. Problematisch wird der ressourcenbasierte Ansatz allerdings immer dann, wenn komplexe Anfragen beantwortet werden sollen, wie uns das Beispiel des Star-Wars-Universums zeigt.
Neulich fragte mich mein ältester Sohn, ob Luke Skywalker eigentlich in allen Star-Wars-Filmen mitgespielt hat. Ich war mir zwar sicher, dass die Antwort auf diese Frage ein klares Nein ist, konnte aber auf Anhieb nicht sagen, in welchen Filmen er dabei war und in welchen nicht. Wie gut also, dass es ein nettes kleines REST-API namens SWAPI [1] gibt, das genau diese Art von Fragen beantwortet. Also schnell https://swapi.co/api/people/1 in den Browser getippt, damit ein GET auf den URI ausgelöst, und schon hatten wir die Antwort in Form eines JSON Records, wie Listing 1 zeigt.
Listing 1: SWAPI REST Call für „Luke Skywalker“
{
"name": "Luke Skywalker",
"height": "172",
"mass": "77",
"hair_color": "blond",
"skin_color": "fair",
"eye_color": "blue",
"birth_year": "19BBY",
"gender": "male",
"homeworld": "http://swapi.co/api/planets/1/",
"films": [
"http://swapi.co/api/films/6/",
"http://swapi.co/api/films/3/",
"http://swapi.co/api/films/2/",
"http://swapi.co/api/films/1/",
"http://swapi.co/api/films/7/"
],
"species": [
"http://swapi.co/api/species/1/"
],
"vehicles": [
"http://swapi.co/api/vehicles/14/",
"http://swapi.co/api/vehicles/30/"
],
"starships": [
"http://swapi.co/api/starships/12/",
"http://swapi.co/api/starships/22/"
],
"created": "2014-12-09T13:50:51.644000Z",
"edited": "2014-12-20T21:17:56.891000Z",
"url": "http://swapi.co/api/people/1/"
}
So weit, so gut – oder eben auch nicht. Denn der REST Response brachte meinen Sohn gleich auf eine ganze Reihe neuer Ideen und Fragen. Er wollte z. B. wissen, wie denn die Episoden genau heißen, in denen Luke mitgespielt hat und mit welchem Spruch der jeweilige Film beginnt. Und dann natürlich noch, mit welchen Raumschiffen Luke in den Filmen geflogen ist und was deren Maximalgeschwindigkeit ist. Und wo wir schon dabei sind, wo kommt Luke überhaupt her, also welcher ist sein Heimatplanet?
Mit ein wenig Mühe und noch mehr Tipparbeit ließen sich am Ende dank SWAPI nahezu alle Fragen meines Sohns beantworten. Es zeigte sich aber auch, dass das REST-basierte API nicht wirklich optimal für derartige Anfragen ausgelegt ist. Möchte man z. B. wissen, in welchen Filmen Luke mitgespielt hat und wie sie heißen, muss zunächst ein GET auf die Ressource people/1 aufgerufen werden, um dann im Anschluss für jeden dort referenzierten Film ein weiteres GET auf der Ressource films/x aufzurufen. Möchte man dann zusätzlich noch wissen, welche Charaktere in dem jeweiligen Film noch mitgespielt haben und in welchen weiteren Filmen sie vertreten waren, hat man schnell das Gefühl, in einer Endlosschleife gefangen zu sein. Eine eigentlich einfache Anfrage endet, bedingt durch den ressourcenbasierten Ansatz, schnell in unzähligen Client-Server-Roundtrips. Natürlich ließe sich dieses Problem durch die Einführung von virtuellen Ressourcen und entsprechenden Endpoints ein wenig entschärfen – in Anlehnung an DB Table Views. So findet man z. B. häufig in REST-APIs eine virtuelle Ressource search, die zur Volltextsuche über alle Ressourcen oder zur gezielten feldbasierten Suche innerhalb einer Ressource herangezogen werden kann. Alternativ ließen sich in unserem Beispiel die Detailinformationen der Ressource film in die JSON-Information der Ressource people einbetten. Das ist aber nicht wirklich REST-alike und würde den zu übertragenden Payload unnötig aufblähen.
Und genau da sind wir schon bei einem weiteren Problem des REST-basierten (SW)API. Möchten wir z. B. von Luke lediglich die Größe und Haarfarbe erfragen, werden wir mit dem oben aufgezeigten Call gleich mit einer ganzen Reihe nicht gewünschter Informationen überhäuft – aka Payload. Um diese einzuschränken, bräuchten wir einen Query-Parameter, wie people/1?fields=a,b,c, der serverseitig zur Filterung der Rückgabefelder genutzt werden kann. Diesen stellt das API leider nicht zur Verfügung. Es müsste also entsprechend erweitert werden. Möchte man darüber hinaus noch mittels URI eine Kombination aus Suchbegriffen, Bedingungen (AND, OR) und Filteroptionen angeben, ist man schnell dabei, das Rad in Form einer eigenen REST Query Language neu zu erfinden. Aber möchte man das wirklich?
Natürlich nicht, denn mit der Resource Query Language aka RQL [2], steht bereits eine fertige Open-Source-Lösung für genau dieses Problem zur Verfügung. RQL ist ein Superset von FIQL (Feed Item Query Language), das speziell zur Abfrage von Object Style Data Structures konzipiert wurde, also auch REST-Ressourcen. Möchte man z. B. alle people-Ressourcen mit blondem Haar herausfinden, die größer als 1,70 Meter sind, dann würde die Anfrage wie folgt aussehen:
GET /people?query=and(eq(hair_color,blond),gt(height,170))
Neben einer Spezifikation der Grammatik und einem JS-Parser bietet RQL Unterstützung bei der Anbindung verschiedener Datenquellen (JS Array, SQL, MongoDB, Elasticsearch). Und auch ein Java-Parser sowie ein JPA Criteria Builder stehen zur Verfügung. Mit ihrer Hilfe lassen sich RQL-Anfragen serverseitig mit wenig Aufwand direkt in Criteria-API-Anfragen umwandeln. Zugegeben, RQL nimmt einem auf jeden Fall die Arbeit ab, für das hauseigene REST-API eine eigene Abfragegrammatik entwickeln zu müssen. Ganz zu schweigen von dem zugehörigen Parser und der Übersetzung des geparsten Ergebnisses in JPA. Das eigentliche Problem, nämlich die Abbildung einer komplexen Abfrage via REST-API, wird durch RQL aber nicht wirklich angegangen.
„Umdenken du musst!“ So oder ähnlich würde es wohl Yoda formulieren. Was wäre, wenn man gemäß CQRS-Pattern (Command Query Responsibility Segregation [3]) zwischen der lesenden und der schreibenden Seite/Domäne unterscheiden würde? In diesem Fall würde das REST-API lediglich für das Anlegen, Ändern oder Löschen einer oder mehrerer Ressourcen verwendet werden. Komplexere Abfragen dagegen liefen über einen separaten Kanal. Dieses Vorgehen würde es uns erlauben, das lesende Modell so zu optimieren, dass wir stets mit einem Roundtrip zum Ergebnis gelangen. Genau das ist auch die Motivation für das seit 2012 von Facebook genutzte und 2015 offiziell als Open-Source-Lösung freigegebene Data-Fetching-API namens GraphQL [4], [5].
We see a conflict between the desire to load all information in a single round trip while keeping REST resources well isolated.
Lee Byron, Facebook
Die Idee hinter GraphQL ist, dass man via Abfrage beliebig auf einem Graphen navigiert und dort genau die Felder abfragt, die einen interessieren. Die Abfrage spiegelt somit nahezu 1:1 die erwartete Antwort wider. Mehrfache Roundtrips oder komplizierte, clientseitige Joins werden obsolet. Stellen wir uns als Beispiel einmal die vielen Fragen meines Sohnes zu Luke vor:
Wie alt ist Luke und welche Haarfarbe hat er?
Mit welchem Spruch wurden die Filme eröffnet, in denen er mitgespielt hat?
Und wie teuer waren die Schiffe, auf denen er gefahren ist?
Wie ließen sich diese Fragen nun in einer einzigen GraphQL-Anfrage verdichten? Ganz einfach, wie Listing 2 zeigt.
Listing 2: SWAPI GraphQL Call für „Luke Skywalker“
{
person(name:"Luke") {
haircolor,
age,
films {
name,
openingCrawl
}
starships {
name,
price
}
}
}
Möglich wird das, indem serverseitig die verschiedenen Datentypen (person, film, starship ...), deren mögliche Attribute inklusive eventueller Parametrisierungen sowie die Relationen der Typen untereinander deklariert werden. Hierdurch erhalten wir automatisch eine streng typisierte und introspektive Abfragesprache. Oder anders formuliert: Dank der verschiedenen Typen kann GraphQL relativ einfach die Korrektheit einer Anfrage feststellen und im Fehlerfall aussagekräftige Fehlermeldungen liefern. Darüber hinaus erlaubt es die Deklaration, eine Schnittstelle nach den möglichen Datentypen und deren Relationen abzufragen. Woher weiß nun aber der Server, wie er mit einer eingehenden GraphQL-Anfrage umgehen muss? Zum einen nutzt GraphQL das bereits erwähnte API-Schema als gemeinsame Basis für Client und Server. Zum anderen findet auf dem Server ein dreistufiger Prozess statt:
Step 1: parse (AST erzeugen)
Step 2: validate (via Schema)
Step 3: execute (via Resolver Functions)
Im Rahmen dieses Prozesses wird die Anfrage zunächst auf syntaktische und semantische Korrektheit geprüft und im Anschluss ausgeführt. Zur Ausführung werden serverseitig verschiedene Resolver Functions aufgerufen, deren Ergebnisse ebenfalls auf dem Server aggregiert werden. Das Ergebnis wird im Anschluss in einem einzigen Roundtrip an den Client zurückgeliefert.
Mittlerweile gibt es für nahezu jede Programmiersprache Clients, Server, DB-Anbindungen und Libraries. Eine gute Übersicht hierzu findet sich auf GitHub unter [6]. Wer auf den Geschmack gekommen ist, kann GraphQL unter [7] einmal selbst ausgiebig ausprobieren, auch am Beispiel Star Wars.
REST-APIs bieten sich nicht wirklich für komplexe Abfragen an. Das gilt insbesondere dann, wenn die Abfrage nicht nur eine, sondern wie in unserem Beispiel gleich mehrere Ressourcen betrifft. Virtuelle Ressourcen und eine spezielle Abfragesprache à la RQL können hier zwar helfen, lösen aber nicht das eigentliche Problem der unerwünschten Client-Server-Roundtrips. Eine mögliche Alternative stellt das Data Fetching API GraphQL von Facebook dar. Mittels JSON-Anfrage wird ein Navigationspfad inkl. der gewünschten Rückgabetypen und -felder an den Server gesandt. Dieser nutzt eigens dafür implementierte Resolver Functions, um Teilergebnisse aus verschiedenen Datenquellen abzufragen, aggregiert diese im Anschluss und schickt sie abschließend in einem einzigen Roundtrip zurück an den Client.
Zugegeben, GraphQL ist eine noch recht junge Technologie. Entsprechend ist auch noch das eine oder andere Optimierungspotenzial vorhanden. So ist es anders als bei REST z. B. nicht ganz trivial, sinnvolle Caches aufzubauen. Das gilt insbesondere dann, wenn Abfrageergebnisse sich nur in Teilbäumen decken. Ein weiteres Problem stellt die Versionierung dar. GraphQL kennt per Definition keine Versionierung, sondern arbeitet mit „deprecated“-Attributen. Breaking Changes in dem API können so zu einem echten Problem für den Client werden. Last but not least ist man als API-Designer bei der Verwendung von GraphQL versucht, Details des zugrunde liegenden Modells nach außen hin bekannt zu geben und somit den Server angreifbar zu machen. Die Umsetzung des Information Hiding Patterns erfordert entsprechend zusätzlichen Aufwand und Disziplin. Trotz der aufgezeigten Herausforderungen stellt GraphQL eine gute Alternative für APIs dar, die bezüglich Abfragen besonders flexibel sein müssen. Für einige der angesprochenen Probleme existieren bereits Lösungsvorschläge, so z. B. für das serverseitige Cachen von Teilergebnissen. Man darf gespannt sein, wie sich das Projekt weiterentwickelt. In diesem Sinn: Stay tuned!
Lars Röwekamp ist Geschäftsführer der open knowledge GmbH und berät seit mehr als zehn Jahren Kunden in internationalen Projekten rund um das Thema Enterprise Computing.
[1] SWAPI: https://swapi.co
[2] RQL: https://github.com/persvr/rql
[3] CQRS: http://martinfowler.com/bliki/CQRS.html
[4] GraphQL: https://graphQL.org
[5] GraphQL Spec: http://facebook.github.io/graphql/
[6] GraphGL Resources: https://github.com/chentsulin/awesome-graphql
[7] SWAPI in GraphQL: http://swapi.graphene-python.org/graphql